IncompatibleClassChangeError from okhttp3.internal.Util.closeQuietly() - android

Seeing the following stack on old versions of Android (4.3 and earlier):
Caused by: java.lang.IncompatibleClassChangeError: interface not implemented
at okhttp3.internal.Util.closeQuietly(Util.java:100)
at okhttp3.internal.connection.StreamAllocation.streamFailed(StreamAllocation.java:332)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.recover(RetryAndFollowUpInterceptor.java:209)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:132)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
at okhttp3.RealCall.execute(RealCall.java:63)
This seems to suggest an incompatibility between okhttp and Java 6, where java.net.Socket doesn't implement Closeable.
And the problem appears to occur primarily as a result of a failed stream. It was difficult to reproduce until we started calling this php page (borrowed from https://stackoverflow.com/a/141026/315702), which forces a stream failure on the client side:
<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // just to be safe
ob_start();
echo('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
sleep(30);
echo('Text user will never see');
?>

This appears to be a bug with the current okhttp 3.6.0-SNAPSHOT build. I filed a bug report on the okhttp github site. The exception is thrown when the connection closes unexpectedly. [Update: the bug was quickly fixed by replacing Closeable with Socket for backward compatibility with Java 6 in this pull request.]
In our case, the real heart of the problem was that we didn't mean to use okhttp 3.6.0-SNAPSHOT in the first place. In our build.gradle, we specified 3.4.1. It turned out one of our third-party libraries had a dependency on okhttp:+, which we discovered via the following gradle command:
./gradlew -q :app:dependencyInsight --dependency okhttp --configuration compile
Because of this, we were pulling in whatever happens to be the latest version of okhttp. In our case, the culprit library was the okhttp extension to exoplayer. By excluding the unwanted module dependency on okhttp:+, we were able to avoid loading 3.6.0-SNAPSHOT:
compile('com.google.android.exoplayer:extension-okhttp:r2.0.4') {
exclude module: 'okhttp'
}

Related

How to fix a "java.io.IOException: unexpected end of stream on Connection" exception in HTTPClient on .NetStandard

I have been scratching my head with this one for a while. I'm building an Android app in Xamarin and I have a login POST request that mostly works, but will occasionally recieve this error. I notify the user and tell them to try again but I am still getting the error far too often and want to fix it so the app provides a smoother experience.
Here is the stack trace I have logged on App Center:
LoginProvider+d__1.MoveNext () C:\source\repos{MyApp}{MyApp}{MyApp}\Services\LoginProvider.cs:35
java.io.IOException: unexpected end of stream on Connection{testclarity.i-menzies.com:443, proxy=DIRECT# hostAddress=62.244.173.166 cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 protocol=http/1.1} (recycle count=0)
com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:210)
com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:905)
com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:789)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:443)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:501)
com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25)
Caused by: java.io.EOFException: \n not found: size=0 content=...
com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:200)
com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
I am using .NETStandard 2.0, with Xamarin Forms 3.2.0.871581.
I have scoured most of Google and identified that this is an issue with various Android libraries, especially OkHttp (the same one mentioned in my stack trace). I've tried investigating the .NETStandard source on Github to identify the possible cause, but I find the project very difficult to navigate, especially as this problem seems to be Android specific. Any advice on finding the right source would be ideal.
Things I have tried based on suggestions from the internet:
Setting my connection header to closed.
Setting my transfer encoding
to chunked.
Swapping out the Android HttpClient implementation from
Android to Default in the Android project's properties.
These seem to be among the popular suggestions online, some of which work for people, some of which don't.
Another common suggestion is setting the OkHttp library's configuration to OkHTTP.setRetryOnConnectionFailure(true), which apparently fixes the problem for many people, as suggested here: https://github.com/square/okhttp/issues/1517#issuecomment-144069139.
Also, a similar bug seems to have been filed in Xamarin.Android here: https://bugzilla.xamarin.com/show_bug.cgi?id=41100. But this has been marked as fixed. I'm not sure whether this would feed into my Xamarin Forms project.
Does anyone know how I can fix this problem or how I can investigate further beyond what I've already tried?
After following the information in this link: https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/http-stack?tabs=macos
And changing my HTTPHandler to the native android handler:
The Xamarin.Android HttpClient configuration is in Project Options >
Android Options, then click the Advanced Options button.
These are the recommended settings for TLS 1.2 support:
Visual Studio Android Options
The one extra bit I missed was:
Projects must reference the System.Net.Http assembly.
Make sure your project references System.Net.Http otherwise it will still use OKHttp
You can just go the Android Project > Properties > AssemblyInfo.cs file.
Open the AssemblyInfo file and add the following line at the end:
[assembly: Application(UsesCleartextTraffic = true)]
This helped me solve my problem. I hope it helps you also
I was having the same issue and been tracing for this fix. My project reference
to System.Net.Http.
I was changing my HTTPHandler to the native android handler when I got this exception but getting kinda similar system exception when using a different HTTPHandler.
I tried a lot of suggestions and finally fixes the issue by using https in my base URL. Here's my reference: https://github.com/square/okhttp/issues/1517#issuecomment-560486265
IMO, the fix might be different in each case, so you might want to try other suggestions.

Exception on streaming the audio on android media player, on okhttp buffering

E/JavaBinder: *** Uncaught remote exception! (Exceptions are not yet supported across processes.)
java.lang.ArrayIndexOutOfBoundsException: length=8192; index=8192
at com.android.okhttp.okio.Buffer.writeByte(Buffer.java:973)
at com.android.okhttp.internal.Platform.concatLengthPrefixed(Platform.java:212)
at com.android.okhttp.internal.Platform.configureTlsExtensions(Platform.java:116)
at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:187)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:149)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:538)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:26)
at android.media.MediaHTTPConnection.seekTo(MediaHTTPConnection.java:212)
at android.media.MediaHTTPConnection.getSize(MediaHTTPConnection.java:374)
at android.media.IMediaHTTPConnection$Stub.onTransact(IMediaHTTPConnection.java:81)
at android.os.Binder.execTransact(Binder.java:731)
This exception occurs on android media player streaming and buffering, the player got stuck on the same position for unusual period of time and sometimes forever.
I don't think there's much you can do. It's been reported to the okhttp devs. But, as they point out, the error is with the internally packaged version of okhttp that is included with android. There's no bug with square's externally developed version, so they have rightfully closed the issue as a non-issue.
The bug has been reported to google, but it doesn't look like any action has been taken in the last almost 2 years.
Perhaps you could include the newer, upstream version of okhttp from square in your project and somehow tell MediaHTTPConnection to use the okhttp3 implementation of HttpURLConnection. There's the OkUrlFactory that could be used with java's URL.setURLStreamHandlerFactory. However that's deprecated and it might not be a good idea to override the built-in url stream handler logic.
In fact, it's been removed from recent versions of okhttp. The dev who removed it did make an ObsoleteUrlFactory.java that you can copy/paste yourself into your project and use as:
OkHttpClient okHttpClient = new OkHttpClient();
URL.setURLStreamHandlerFactory(new ObsoleteUrlFactory(okHttpClient));

okHttp3 java.lang.NoSuchMethodError: No virtual method setCallWebSocket

I've updated from okhttp + retrofit to okhttp3 + retrofit2 but my app doesn't start cause of this Exception
FATAL EXCEPTION: EventThread
Process: appli.speaky.com, PID: 14705
java.lang.NoSuchMethodError: No virtual method setCallWebSocket(Lokhttp3/Call;)V in class Lokhttp3/internal/Internal; or its super classes (declaration of 'okhttp3.internal.Internal' appears in /data/data/appli.example.com/files/instant-run/dex/slice-okhttp-3.6.0_29bb10e5f590229716bfa8daf196d09ea67f56a8-classes.dex)
at okhttp3.ws.WebSocketCall.enqueue(WebSocketCall.java:108)
at io.socket.engineio.client.transports.WebSocket.doOpen(WebSocket.java:84)
at io.socket.engineio.client.Transport$1.run(Transport.java:82)
at io.socket.thread.EventThread.exec(EventThread.java:55)
at io.socket.engineio.client.Transport.open(Transport.java:77)
at io.socket.engineio.client.Socket.probe(Socket.java:472)
at io.socket.engineio.client.Socket.onOpen(Socket.java:485)
at io.socket.engineio.client.Socket.onHandshake(Socket.java:526)
at io.socket.engineio.client.Socket.onPacket(Socket.java:499)
at io.socket.engineio.client.Socket.access$1000(Socket.java:31)
at io.socket.engineio.client.Socket$5.call(Socket.java:313)
at io.socket.emitter.Emitter.emit(Emitter.java:117)
at io.socket.engineio.client.Transport.onPacket(Transport.java:134)
at io.socket.engineio.client.transports.Polling.access$700(Polling.java:17)
at io.socket.engineio.client.transports.Polling$2.call(Polling.java:124)
at io.socket.engineio.parser.Parser.decodePayload(Parser.java:251)
at io.socket.engineio.client.transports.Polling._onData(Polling.java:134)
at io.socket.engineio.client.transports.Polling.onData(Polling.java:106)
at io.socket.engineio.client.transports.PollingXHR$5$1.run(PollingXHR.java:111)
at io.socket.thread.EventThread$2.run(EventThread.java:80)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
I also had the same issue. The issue was I am using socket 0.8.0 which I think has conflict with OKHTTP websocket implem.
Upon upgrading to the latest version of socket.io
compile('io.socket:socket.io-client:0.8.3') {
exclude group: 'org.json', module: 'json'
}
and also using the latest version of OKHTTP (no need to include okhttp-ws)
compile "com.squareup.okhttp3:okhttp:3.7.0"
compile "com.squareup.okhttp3:logging-interceptor:3.7.0"
my app is not crashing upon first load and it is connecting to sockets. Interceptor also has no conflict whatsoever and is logging as expected on logcat.
With this, there is no need to downgrade your version of okHTTP for which it has been the working solution in the past. :)
Hi there,I have the same issue just days ago(my app is a react-native) ,I just use the 3.4.1 version to replace the latest,and solved it!
compile "com.squareup.okhttp3:okhttp:3.4.1"
compile "com.squareup.okhttp3:logging-interceptor:3.4.1"
and I guess it is caused by the Retrofit2's okhttp lib
I had this issue after launching the Android Studio Profiler, even after closing the profiler. Had to restart Android Studio to fix it.
I had similar issue. Problem with my project was it was using okhttp-3.3.1 which do not have method setCallWebSocket.
Make sure you add correct version of okhttp in your gradle and the older version which does not have setCallWebSocket are not included elsewhere under your project libraries or dependencies.

Getting socket timeout exception while uploading image with Retrofit in Nexus devices

I am uploading the image to the server using Retrofit with Okhttp. Everything works fine but I am getting socket exception only with the Nexus 5X and 6P devices.
Exception that I am getting:
java.net.SocketTimeoutException: failed to connect to backup.server.gcm.com (port 8067) after 10000ms
Fixes that I tried:
Changing tcp_timestamp by sysctl from server side.
Added '/' slash at the end of url (As per the StackOverflow solution that i found).
Added android:vmSafeMode="true" in application manifest (As per the Github solution in issues).
I almost tried all the possible solutions from my side and nothing works. I am completely stuck with this weird behaviour. Please help me for the same. Any kinda tip and suggestion would be really helpful to me. Also i found issues related this in github which are not unanswered as follows:
https://github.com/square/okhttp/issues/1771
https://github.com/square/okhttp/issues/2794
build.gradle
dependencies {
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.retrofit2:retrofit:2.0.1'
}

Android Studio 2.1.2 http GET error

I have been fighting with this for 2 days now, end of the line for me. It seems I am having trouble in getting my makeHttpRequest. I can add data, view all records in a table but I just can't seem to get a single record data to my page, app crashes completely "Unfortunately 'app_name" has stopped.
Below is my JSonParser file and the Activity file. Any suggestions will be welcome. I have read through tons of similar questions but none seemed to have worked...
Thanks all.
Errors in JsonParser as per image 'JSonParser, no errors in my Activity file as per image 'Activity'JSonParser
Log error as follow ---
FATAL EXCEPTION: main
Process: ...MyApp.co.za.androidtophp, PID: 32447
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
at java.net.InetAddress.lookupHostByName(InetAddress.java:431)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:185)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:172)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:130)
at org.apache.http.impl.client.DefaultRequestDirector.executeOriginal(DefaultRequestDirector.java:1337)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:705)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:578)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:494)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:472)
at ...MyApp.co.za.androidtophp.JSONParser.makeHttpRequest(JSONParser.java:63)
at ...MyApp.co.za.androidtophp.EditProductActivity$GetProductDetails$1.run(EditProductActivity.java:134)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Gradle files is all in there as far as apache is concerned -
useLibrary 'org.apache.http.legacy'
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.1.1'
compile 'com.android.support:appcompat-v7:24.1.1'
compile 'com.android.support:design:24.1.1'
compile 'com.android.volley:volley:1.0.0'
compile 'com.google.code.gson:gson:2.6.2'
compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1'
Never execute longer running task on main thread specially during network calls where you have no idea when the response will come due to various factors like signal strength , server crash/busy etc.
Put your all network call either in Asynchtasks if they are relatively small like download image around 1-3 MB, doc/files etc or for longer tasks use HTTPUrlConncetion calls or you can use some networking libraries for better memory usage and optimizations , efficient cache mechanism.
Volley
Easy to use
Matured and backed by google
Retrofit
Has inbuild integration/support with useful libraries like
GSON - for parsing JSONObject/JSONArrays
Okio to support java.io and java.nio to make it much easier to access, store and process your data using ByteString and Buffer
RxJava - Observable patterns
though the above libraries like GSON etc can be used with Volley too as a separate dependancy.
There are many other open source libraries like Ion , OKHttp etc too, though the above are more popular but if you want your own customization then you can simply use HTTPUrlConncetion.
Try this link for networking call examples using threads and for more info about network libraries try comparison between OkHTTP, Retrofit, Volley .
There also some better options for Image downloading network calls i.e you can use Picasso , Glide , Fresco , Universal Image loader etc. try this link for image downloading libraries
That is happening because you are trying to make the HTTP Request synchronous. Please create an AsyncTask or disable strict mode (only clever when there's no problem when the app could hange some seconds).
Warning: Don't use this for public app releases!!!
For disabling Strict Mode, add following code in your onCreate() (right after super.onCreate(savedInstanceState))
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

Categories

Resources