okhttp icon indicating copy to clipboard operation
okhttp copied to clipboard

java.lang.UnsupportedOperationException when using OkHttp 3.12.12 on Android 10 (API 29)

Open marosseleng opened this issue 4 years ago • 9 comments

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.

marosseleng avatar Jul 28 '20 13:07 marosseleng

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.

yschimke avatar Jul 28 '20 17:07 yschimke

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

marosseleng avatar Jul 29 '20 14:07 marosseleng

I encountered the same problem, but it appeared on some phones, is there a solution here? Can OkHttp catch this exception?@yschimke

lbybug avatar Oct 14 '20 08:10 lbybug

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?

yschimke avatar Oct 14 '20 09:10 yschimke

Yes, we use a custom socket factory, but this exception is not inevitable and difficult to locate

lbybug avatar Oct 14 '20 09:10 lbybug

What does that do?

yschimke avatar Oct 14 '20 10:10 yschimke

Same crash we meet. We change the version to 3.12.8, the crash gone. 3.12.9 and above are all crash.

ibosong avatar Sep 13 '21 08:09 ibosong

@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 avatar Sep 14 '21 06:09 yschimke

@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.

ibosong avatar Sep 15 '21 03:09 ibosong

Closing as 3.x is unsupported

yschimke avatar May 21 '23 08:05 yschimke