okhttp
okhttp copied to clipboard
java.lang.UnsupportedOperationException when using OkHttp 3.12.12 on Android 10 (API 29)
Hi all,
I am developing an Android app, where I use my small library to handle network operations out of main apps, so it could be reused. The setup is as follows:
Network library:
- OhHttp 3.12.12
- Retrofit 2.6.4
- conscrypt 2.2.1
- minSdkVersion 15 (that's why we have to stay with 3.12)
- targetSdkVersion 29
The app:
- minSdkVersion 15
- targetSdkVersion 29
When I execute a request on Android 10, it fails with the following stacktrace:
2020-07-28 15:06:09.056 14386-14430/com.example.testapp W/System.err: java.lang.UnsupportedOperationException
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at javax.net.ssl.SSLSocket.getApplicationProtocol(SSLSocket.java:1467)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.platform.Android10Platform.getSelectedProtocol(Android10Platform.java:63)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:347)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:284)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:169)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:258)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:127)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:225)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:257)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at okhttp3.RealCall.execute(RealCall.java:93)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at retrofit2.OkHttpCall.execute(OkHttpCall.java:188)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall.execute(DefaultCallAdapterFactory.java:104)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at com.example.networklib.api.TestApi.sendData(TestApi.java:89)
2020-07-28 15:06:09.057 14386-14430/com.example.testapp W/System.err: at com.example.testapp.fragment.NewRequestFragment$1.doInBackground(NewRequestFragment.java:130)
2020-07-28 15:06:09.058 14386-14430/com.example.testapp W/System.err: at com.example.testapp.fragment.NewRequestFragment$1.doInBackground(NewRequestFragment.java:93)
2020-07-28 15:06:09.058 14386-14430/com.example.testapp W/System.err: at android.os.AsyncTask$3.call(AsyncTask.java:378)
2020-07-28 15:06:09.058 14386-14430/com.example.testapp W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2020-07-28 15:06:09.058 14386-14430/com.example.testapp W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
2020-07-28 15:06:09.058 14386-14430/com.example.testapp W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2020-07-28 15:06:09.058 14386-14430/com.example.testapp W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2020-07-28 15:06:09.058 14386-14430/com.example.testapp W/System.err: at java.lang.Thread.run(Thread.java:919)
It seems that it ignores Conscrypt being present (and loaded) and tries to load the base SSLSocket
which throws the exception. Is this a bug in OkHttp or in the Android framework itself?
I would apreciate any help. We cannot, however, update minSdkVersion
.
How are you registering Conscrypt?
https://github.com/square/okhttp/blob/d479b0e41c6511ddb4ba650e9fe584440ce236f5/README.md
Security.insertProviderAt(Conscrypt.newProvider(), 1);
Can you make a reproduction project, or adapt the existing Android tests to trigger this? Without this there is not much we can do.
Yep, I am registering it according to tutorial.
Anyway, turns out, custom SSLSocketFactory was causing this issue for us. Thus I suggest closing the issue as non-reproducible. Thanks
I encountered the same problem, but it appeared on some phones, is there a solution here? Can OkHttp catch this exception?@yschimke
Not without a clean reproduction, we don't want to hide root causes and normalise them. Can you make a repro? Do you have something similar like a custom socket factory?
Yes, we use a custom socket factory, but this exception is not inevitable and difficult to locate
What does that do?
Same crash we meet. We change the version to 3.12.8, the crash gone. 3.12.9 and above are all crash.
@ibosong We can put a fix in, we already handle this in other cases, but because we know Android 10 standard ssl sockets supports this we didn't handle this case.
But what's your goal here? Do you want a socket that deliberately doesn't support ALPN? Or you just didn't remember to implement? Or it comes from a third party library?
If you have your own custom SSL Socket, As a workaround for 3.12.12 you can implement and return "".
@yschimke We have a custom SSLSocket, but the default getApplicationProtocol method throw this exception and we don't implement this method since it's not abstract, and we miss this. Thanks for your reply, I think we have a solution.
Closing as 3.x is unsupported