JDK 17 (JEP 403 Strongly Encapsulate JDK Internals) breaks okhttp without additional config
$ java --version sgopal1@m-c02xd0kqjgh7
openjdk 17-loom 2021-09-14
OpenJDK Runtime Environment (build 17-loom+7-342)
OpenJDK 64-Bit Server VM (build 17-loom+7-342, mixed mode, sharing)
// OkHttp
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.0"))
implementation("com.squareup.okhttp3:okhttp")
Throws the following error when trying to create an OkHttpClient on JDK17-ea build with strong encapsulation enabled.
java.lang.reflect.InaccessibleObjectException: Unable to make field private final sun.security.ssl.SSLContextImpl sun.security.ssl.SSLSocketFactoryImpl.context accessible: module java.base does not "opens sun.security.ssl" to unnamed module @3a44f074
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:177)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:171)
at okhttp3.internal.Platform.readFieldOrNull(Platform.java:417)
at okhttp3.internal.Platform.trustManager(Platform.java:91)
at okhttp3.OkHttpClient.<init>(OkHttpClient.java:184)
at okhttp3.OkHttpClient.<init>(OkHttpClient.java:60)
at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:718)
at se.bjurr.gitchangelog.internal.integrations.github.GitHubServiceFactory.getGitHubService(GitHubServiceFactory.java:55)
Have to explicitly open this package for reflection in all (--add-opens java.base/sun.security.ssl=ALL-UNNAMED
) the programs for okhttp to work properly.
Source: https://github.com/square/okhttp/blob/master/okhttp/src/main/kotlin/okhttp3/internal/platform/Platform.kt#L93
Looks like a clean fix is to log and swallow this exception
open fun trustManager(sslSocketFactory: SSLSocketFactory): X509TrustManager? {
return try {
// Attempt to get the trust manager from an OpenJDK socket factory. We attempt this on all
// platforms in order to support Robolectric, which mixes classes from both Android and the
// Oracle JDK. Note that we don't support HTTP/2 or other nice features on Robolectric.
val sslContextClass = Class.forName("sun.security.ssl.SSLContextImpl")
val context = readFieldOrNull(sslSocketFactory, sslContextClass, "context") ?: return null
readFieldOrNull(context, X509TrustManager::class.java, "trustManager")
} catch (e: ClassNotFoundException) {
@sureshg Something is off with the java files and line numbers in your stacktrace. Can you easily test if we give you a snapshot?
https://github.com/square/okhttp/blob/parent-4.9.0/okhttp/src/main/kotlin/okhttp3/OkHttpClient.kt#L184
Something is off with the java files
@yschimke My bad, yes you are correct. The issue is due to an old OKHttp dependency used in the Gradle plugin. I did test the latest OKHttp release on JDK 18 and it's running smoothly without any issues/warnings 👍🏼 .
Here is the link JDK18 github action run logs on win/linux/macos - https://github.com/sureshg/okhttp-jdk-test/runs/2836840606?check_suite_focus=true
Again, really sorry for the inconvenience caused.
I don't think it's trivial to test for this, as I suspect that the Gradle 7.2 + Junit code needs to avoid this anyway.
package okhttp3;
import org.junit.jupiter.api.Test;
import javax.net.ssl.SSLSocketFactory;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class Jdk17Test {
@Test
public void testDeprecatedSslSocketFactory() {
// https://github.com/square/okhttp/issues/6694
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
try {
new OkHttpClient.Builder().sslSocketFactory(factory).build();
} catch (UnsupportedOperationException uoe) {
// expected
assertEquals("clientBuilder.sslSocketFactory(SSLSocketFactory) not supported on " +
"JDK 8 (>= 252) or JDK 9+",
uoe.getMessage());
Is passing even if I disable the fix.