包衝突
錯誤原因
使用OSS Java SDK時,報類似如下錯誤,說明您的工程裡可能有包衝突。
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/ssl/TrustStrategy
at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268)
at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193)
at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:77)
Caused by: java.lang.ClassNotFoundException: org.apache.http.ssl.TrustStrategy
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 3 more
或
Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE
at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52)
at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:56)
at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<clinit>(DefaultHttpRequestWriterFactory.java:46)
at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:82)
at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:95)
at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:104)
at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<clinit>(ManagedHttpClientConnectionFactory.java:62)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$InternalConnectionFactory.<init>(PoolingHttpClientConnectionManager.java:572)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:174)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:158)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:149)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:125)
at com.aliyun.oss.common.comm.DefaultServiceClient.createHttpClientConnectionManager(DefaultServiceClient.java:237)
at com.aliyun.oss.common.comm.DefaultServiceClient.<init>(DefaultServiceClient.java:78)
at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268)
at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193)
at OSSManagerImpl.upload(OSSManagerImpl.java:42)
at OSSManagerImpl.main(OSSManagerImpl.java:63)
錯誤原因是OSS Java SDK使用了Apache httpclient 4.4.1,而您的工程使用了與Apache httpclient 4.4.1衝突的Apache httpclient或commons-httpclient jar包。要查看工程使用的jar包及版本,請在您的工程目錄下執行mvn dependency:tree。如下圖所示,您的工程裡使用了Apache httpclient 4.3:
解決方法
包衝突有以下兩種解決方法:
- 使用統一版本。如果您的工程使用與Apache httpclient 4.4.1衝突的版本,請您使用4.4.1版本,並在pom.xml刪除其它版本的Apache httpclient依賴。如果您的工程使用了commons-httpclient,也可能存在衝突,請刪除commons-httpclient。
- 解除依賴衝突。如果您的工程依賴多個第三方包,而第三方包又依賴不同版本的Apache httpclient,您的工程裡會有依賴衝突,請使用exclusion解除。詳細請參見Maven Guides。
OSS Java SDK依賴以下版本的包,衝突解決辦法與httpclient類似。
缺少包
錯誤原因
使用OSS Java SDK時,報類似如下錯誤,說明您的工程中可能缺少編譯或運行OSS Java SDK所必需的包。
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/auth/Credentials
at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268)
at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193)
at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:76)
Caused by: java.lang.ClassNotFoundException: org.apache.http.auth.Credentials
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 3 more
或
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/protocol/HttpContext
at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268)
at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193)
at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:76)
Caused by: java.lang.ClassNotFoundException: org.apache.http.protocol.HttpContext
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 3 more
或
Exception in thread "main" java.lang.NoClassDefFoundError: org/jdom/input/SAXBuilder
at com.aliyun.oss.internal.ResponseParsers.getXmlRootElement(ResponseParsers.java:645)
at … …
at com.aliyun.oss.OSSClient.doesBucketExist(OSSClient.java:471)
at com.aliyun.oss.OSSClient.doesBucketExist(OSSClient.java:465)
at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:82)
Caused by: java.lang.ClassNotFoundException: org.jdom.input.SAXBuilder
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 11 more
OSS Java SDK依賴下列包:
- aliyun-sdk-oss-2.2.1.jar
- hamcrest-core-1.1.jar
- jdom-1.1.jar
- commons-codec-1.9.jar
- httpclient-4.4.1.jar
- commons-logging-1.2.jar
- httpcore-4.4.1.jar
- log4j-1.2.15.jar
其中log4j-1.2.15.jar是可選的,需要日誌功能的時候加入該包,其它包都是必需的。
解決方法
在您的工程中加入OSS Java SDK依賴的包。加入方法如下:
- 如果您的工程在Eclipse中,請參見Java SDK使用手冊中的安裝方式二:在Eclipse項目中匯入工程依賴的包。
- 如果您的工程在Ant中,請把OSS Java SDK依賴的包放入工程的lib目錄中。
- 如果您直接使用.javac或.java檔案,請使用-classpath或-cp命令指定OSS Java SDK依賴的包路徑,或把OSS Java SDK依賴的包放入classpath路經下。
連接逾時
錯誤原因
運行OSS Java SDK程式時,報類似如下錯誤,可能的原因是Endpoint錯誤或者網路不通。
com.aliyun.oss.ClientException: SocketException
at com.aliyun.oss.common.utils.ExceptionFactory.createNetworkException(ExceptionFactory.java:71)
at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:116)
at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:121)
at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:67)
at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:92)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:140)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:111)
at com.aliyun.oss.internal.OSSBucketOperation.getBucketInfo(OSSBucketOperation.java:1152)
at com.aliyun.oss.OSSClient.getBucketInfo(OSSClient.java:1220)
at com.aliyun.oss.OSSClient.getBucketInfo(OSSClient.java:1214)
at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:94)
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to oss-test.oss-cn-hangzhou-internal.aliyuncs.com:80 [oss-test.oss-cn-hangzhou-internal.aliyuncs.com/10.84.135.99] failed: Connection timed out: connect
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:151)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:113)
... 9 more
解決方法
您可以使用OSSProbe工具快速定位錯誤原因,從而解決問題。
org.apache.http.NoHttpResponseException: The target server failed to respond
錯誤原因
運行OSS Java SDK程式時,報類似如下錯誤:
使用過期的連接會導致上述錯誤。該錯誤僅在Java SDK 2.1.2前的版本出現。
解決方法
請升級OSS Java SDK到2.1.2及以後版本。
調用OSS Java SDK夯住
錯誤原因
調用OSS Java SDK夯住(hang)。通過jstack -l pid命令查看堆棧,夯在如下的位置:
"main" prio=6 tid=0x000000000291e000 nid=0xc40 waiting on condition [0x0000000002dae000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007d85697f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:138)
at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:306)
at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:64)
at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:192)
at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:185)
at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:107)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:276)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:263)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:190)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:113)
at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:123)
at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:68)
at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:94)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:146)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:113)
at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:229)
at com.aliyun.oss.OSSClient.getObject(OSSClient.java:629)
at com.aliyun.oss.OSSClient.getObject(OSSClient.java:617)
at samples.HelloOSS.main(HelloOSS.java:49)
原因是連接池中連接泄漏,可能是使用ossObject後沒有關閉。
解決方法
請檢查您的程式,確保沒有連接泄漏。關閉方法如下:
// 讀取檔案
OSSObject ossObject = ossClient.getObject(bucketName, objectName);
// OSS操作
// 關閉ossObject
ossObject.close();
問題排查的詳細步驟,請參見OSS Java SDK夯住問題排查。
連接關閉
錯誤原因
如果您在使用ossClient.getObject時,報類似如下錯誤:
Exception in thread "main" org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 11990526; received: 202880
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:180)
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:200)
at org.apache.http.impl.io.ContentLengthInputStream.close(ContentLengthInputStream.java:103)
at org.apache.http.impl.execchain.ResponseEntityProxy.streamClosed(ResponseEntityProxy.java:128)
at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:228)
at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:174)
at java.io.FilterInputStream.close(FilterInputStream.java:181)
at java.io.FilterInputStream.close(FilterInputStream.java:181)
at com.aliyun.oss.event.ProgressInputStream.close(ProgressInputStream.java:147)
at java.io.FilterInputStream.close(FilterInputStream.java:181)
at samples.HelloOSS.main(HelloOSS.java:39)
原因是兩次讀取資料間隔時間超過1分鐘。OSS會關閉超過1分鐘沒有發送或接收資料的連接。
解決方法
如果您每次讀取部分資料進行處理,且處理資料的時間不固定,建議使用指定範圍讀取,避免資料讀取時連接關閉。
記憶體泄露
錯誤原因
調用OSS Java SDK的程式,運行一段時間(根據業務量,幾小時到幾天不等)後記憶體泄露。推薦使用Eclipse Memory Analyzer (MAT)分析記憶體使用量情況,使用方法請參見使用MAT進行堆轉儲檔案分析。
如果分析結果類似下圖所示(PoolingHttpClientConnectionManager佔96%的記憶體),原因是程式中可能多次執行new OSSClient,但是沒有調用ossClient.shutdown,造成記憶體流失。
解決方法
new OSSClient一定要和ossClient.shutdown成對使用。
調用ossClient.shutdown拋異常InterruptedException
錯誤原因
調用ossClient.shutdown拋如下異常:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.aliyun.oss.common.comm.IdleConnectionReaper.run(IdleConnectionReaper:76)
原因是ossClient後台線程IdleConnectionReaper會定時關閉閑置連接。IdleConnectionReaper在Sleep時,調用ossClient.shutdown,就會拋出上面的異常。
解決方法
OSS Java SDK 2.3.0已經修複該問題。
OSS Java SDK 2.3.0之前的版本,請使用如下代碼,忽略該異常:
try {
ossClient.shutdown();
} catch(Exception e) {
}
其它錯誤
其它OSS返回錯誤的排查,請參見常見錯誤及排查。