I'm using Android-Query to make HTTP calls, and I keep getting random SSLExceptions, like these:
AQuery(7746): javax.net.ssl.SSLException: Read error: ssl=0x19d3c0: I/O error during system call, Connection reset by peer
AQuery(7746): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_read(Native Method)
AQuery(7746): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:801)
AQuery(7746): at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
AQuery(7746): at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:191)
AQuery(7746): at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:82)
AQuery(7746): at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:174)
AQuery(7746): at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:180)
AQuery(7746): at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:235)
AQuery(7746): at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:259)
AQuery(7746): at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:279)
AQuery(7746): at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:121)
AQuery(7746): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:428)
AQuery(7746): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
AQuery(7746): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
AQuery(7746): at com.androidquery.callback.AbstractAjaxCallback.httpDo(AbstractAjaxCallback.java:1328)
AQuery(7746): at com.androidquery.callback.AbstractAjaxCallback.httpGet(AbstractAjaxCallback.java:1207)
AQuery(7746): at com.androidquery.callback.AbstractAjaxCallback.network(AbstractAjaxCallback.java:1133)
AQuery(7746): at com.androidquery.callback.AbstractAjaxCallback.networkWork(AbstractAjaxCallback.java:986)
AQuery(7746): at com.androidquery.callback.AbstractAjaxCallback.backgroundWork(AbstractAjaxCallback.java:933)
AQuery(7746): at com.androidquery.callback.AbstractAjaxCallback.run(AbstractAjaxCallback.java:894)
AQuery(7746): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081)
AQuery(7746): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:574)
AQuery(7746): at java.lang.Thread.run(Thread.java:1020)
There seems to be no rhyme or reason as to their occurrence. They happen maybe 1/6 of the time I make any calls.
Here is how I'm using Android-Query ($
):
// APPLICATION CREATE:
public void onCreate()
{
AQUtility.setExceptionHandler( new UncaughtExceptionHandler() {
public void uncaughtException( Thread thread, Throwable ex )
{
ex.printStackTrace();
}
} );
AQUtility.setDebug( true );
AjaxCallback.setTransformer( new JsonTransformer() );
//set the max number of concurrent network connections, default is 4
AjaxCallback.setNetworkLimit( 8 );
//set the max number of icons (image width <= 50) to be cached in memory, default is 20
BitmapAjaxCallback.setIconCacheLimit( 20 );
//set the max number of images (image width > 50) to be cached in memory, default is 20
BitmapAjaxCallback.setCacheLimit( 40 );
//set the max size of an image to be cached in memory, default is 1600 pixels (ie. 400x400)
BitmapAjaxCallback.setPixelLimit( 480 * 480 );
//set the max size of the memory cache, default is 1M pixels (4MB) (2---)
BitmapAjaxCallback.setMaxPixelLimit( 4000000 );
super.onCreate();
}
// USAGE // NOTE: uri = // 07-13 17:26:08.040: W/AQuery(7746): get:https://site.com/me/ticker/
$.auth( Security.getAuth( this ) ).ajax( uri, BaseModelListRequest.class, this, "loadAdapterObjectsCallback" );
public void loadAdapterObjectsCallback( String uri, BaseModelListRequest requestData, AjaxStatus status )
{
setProgressBarIndeterminateVisibility( false );
setSupportProgressBarIndeterminateVisibility( false );
if( requestData != null && status.getCode() == 200 )
{
// stuff
}
}
// HERE IS GETAUTH:
public static synchronized BasicHandle getAuth( Context context )
{
return new BasicHandle( "user", "pass" );
}
// AND THE JSONTRANSFORMER (uses jaxson to marshall json):
public class JsonTransformer implements Transformer
{
public < T > T transform( String url, Class< T > type, String encoding, byte[] data, AjaxStatus status )
{
ObjectMapper mapper = new ObjectMapper();
try
{
return mapper.readValue( new String( data ), type );
}
catch( Exception e )
{
return null;
}
}
}
EDIT: This happens on 2.X and 3.X, using SSL. Disabling SSL (https -> http) makes it work.
Here is another exception, with SSL:
07-13 22:03:41.454: W/AQuery(2517): javax.net.ssl.SSLException: Not trusted server certificate
07-13 22:03:41.454: W/AQuery(2517): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:360)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:321)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:140)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
07-13 22:03:41.454: W/AQuery(2517): at com.androidquery.callback.AbstractAjaxCallback.httpDo(AbstractAjaxCallback.java:1328)
07-13 22:03:41.454: W/AQuery(2517): at com.androidquery.callback.AbstractAjaxCallback.httpGet(AbstractAjaxCallback.java:1207)
07-13 22:03:41.454: W/AQuery(2517): at com.androidquery.callback.AbstractAjaxCallback.network(AbstractAjaxCallback.java:1133)
07-13 22:03:41.454: W/AQuery(2517): at com.androidquery.callback.AbstractAjaxCallback.networkWork(AbstractAjaxCallback.java:986)
07-13 22:03:41.454: W/AQuery(2517): at com.androidquery.callback.AbstractAjaxCallback.backgroundWork(AbstractAjaxCallback.java:933)
07-13 22:03:41.454: W/AQuery(2517): at com.androidquery.callback.AbstractAjaxCallback.run(AbstractAjaxCallback.java:894)
07-13 22:03:41.454: W/AQuery(2517): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
07-13 22:03:41.454: W/AQuery(2517): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
07-13 22:03:41.454: W/AQuery(2517): at java.lang.Thread.run(Thread.java:1096)
07-13 22:03:41.454: W/AQuery(2517): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found.
07-13 22:03:41.454: W/AQuery(2517): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:168)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:355)
07-13 22:03:41.454: W/AQuery(2517): ... 17 more
07-13 22:03:41.454: W/AQuery(2517): Caused by: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found.
07-13 22:03:41.454: W/AQuery(2517): at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:149)
07-13 22:03:41.454: W/AQuery(2517): at java.security.cert.CertPathValidator.validate(CertPathValidator.java:211)
07-13 22:03:41.454: W/AQuery(2517): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:164)
07-13 22:03:41.454: W/AQuery(2517): ... 18 more
EDIT 2:
Further inspection yields that the error occurs on Android 2.3.x devices. Removing the "s" in the protocol (ie SSL) makes everything work fine.
I have previously had this issue with RestTemplate (Spring-Android), and fixed it by following this post's recommendations: Self-signed SSL acceptance on Android
However, I modified the source to Android-Query in the same manner, and it did not fix the issue.
This question has been ask a couple of times here and here. This exception seems to be the result of the connection being reset by the server. I don't think there's much you can do in your application code other than to gracefully handle the exception and move on. If the server is under your control it would be worthwhile check the logs and configuration to see what is causing the connection to be reset. You might be able to minimize or resolve the issue there instead.