From b72276ad776852bf136ae9b68dad71eb14592458 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 11 May 2025 15:51:27 +0100 Subject: [PATCH 01/24] Add multi-release jars to enable Java Modules --- build.gradle.kts | 9 ++- buildSrc/build.gradle.kts | 9 ++- buildSrc/src/main/kotlin/JavaModules.kt | 53 ++++++++++++++ mockwebserver-deprecated/build.gradle.kts | 6 +- .../src/main/java9/module-info.java | 4 ++ mockwebserver-junit4/build.gradle.kts | 6 +- .../src/main/java9/module-info.java | 4 ++ mockwebserver-junit5/build.gradle.kts | 7 +- .../src/main/java9/module-info.java | 4 ++ mockwebserver/build.gradle.kts | 6 +- mockwebserver/src/main/java9/module-info.java | 4 ++ okcurl/build.gradle.kts | 2 + okhttp-brotli/build.gradle.kts | 3 +- okhttp-brotli/src/main/java9/module-info.java | 4 ++ okhttp-coroutines/build.gradle.kts | 3 +- .../src/main/java9/module-info.java | 4 ++ okhttp-dnsoverhttps/build.gradle.kts | 3 +- .../src/main/java9/module-info.java | 4 ++ okhttp-java-net-cookiejar/build.gradle.kts | 3 +- .../src/main/java9/module-info.java | 4 ++ okhttp-logging-interceptor/build.gradle.kts | 3 +- .../src/main/java9/module-info.java | 4 ++ okhttp-sse/build.gradle.kts | 3 +- okhttp-sse/src/main/java9/module-info.java | 4 ++ okhttp-tls/build.gradle.kts | 3 +- okhttp-tls/src/main/java9/module-info.java | 4 ++ okhttp-urlconnection/build.gradle.kts | 3 +- .../src/main/java9/module-info.java | 3 + okhttp/build.gradle.kts | 69 ++++++++++++++++++- okhttp/src/jvmMain/java9/module-info.java | 8 +++ 30 files changed, 213 insertions(+), 33 deletions(-) create mode 100644 buildSrc/src/main/kotlin/JavaModules.kt create mode 100644 mockwebserver-deprecated/src/main/java9/module-info.java create mode 100644 mockwebserver-junit4/src/main/java9/module-info.java create mode 100644 mockwebserver-junit5/src/main/java9/module-info.java create mode 100644 mockwebserver/src/main/java9/module-info.java create mode 100644 okhttp-brotli/src/main/java9/module-info.java create mode 100644 okhttp-coroutines/src/main/java9/module-info.java create mode 100644 okhttp-dnsoverhttps/src/main/java9/module-info.java create mode 100644 okhttp-java-net-cookiejar/src/main/java9/module-info.java create mode 100644 okhttp-logging-interceptor/src/main/java9/module-info.java create mode 100644 okhttp-sse/src/main/java9/module-info.java create mode 100644 okhttp-tls/src/main/java9/module-info.java create mode 100644 okhttp-urlconnection/src/main/java9/module-info.java create mode 100644 okhttp/src/jvmMain/java9/module-info.java diff --git a/build.gradle.kts b/build.gradle.kts index b22970d3ca73..f9f273329935 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -265,8 +265,13 @@ subprojects { } tasks.withType { - sourceCompatibility = projectJavaVersion.toString() - targetCompatibility = projectJavaVersion.toString() + if (name.contains("Java9")) { + sourceCompatibility = "9" + targetCompatibility = "9" + } else { + sourceCompatibility = projectJavaVersion.toString() + targetCompatibility = projectJavaVersion.toString() + } } } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 90a3bde87bea..579c33b7cf0f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -15,11 +15,12 @@ */ plugins { - `kotlin-dsl` + `kotlin-dsl` } repositories { - mavenCentral() + mavenCentral() + gradlePluginPortal() } dependencies { @@ -28,4 +29,8 @@ dependencies { // Could not create an instance of type aQute.bnd.gradle.BundleTaskExtension. // Cannot change attributes of configuration ':native-image-tests:compileClasspath' after it has been locked for mutation implementation("biz.aQute.bnd:biz.aQute.bnd.gradle:7.1.0") + + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin-api:2.1.20") + + implementation("me.champeau.mrjar:me.champeau.mrjar.gradle.plugin:0.1.1") } diff --git a/buildSrc/src/main/kotlin/JavaModules.kt b/buildSrc/src/main/kotlin/JavaModules.kt new file mode 100644 index 000000000000..645ff62e6cec --- /dev/null +++ b/buildSrc/src/main/kotlin/JavaModules.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2025 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import me.champeau.mrjar.MultiReleaseExtension +import org.gradle.api.Project +import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.named +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile + +fun Project.applyJavaModules( + moduleName: String, + defaultVersion: Int = 8, + javaModuleVersion: Int = 9, +) { + plugins.apply("me.champeau.mrjar") + + configure { + targetVersions(defaultVersion, javaModuleVersion) + } + + tasks.named("compileJava9Java").configure { + val compileKotlinTask = tasks.getByName("compileKotlin") as KotlinJvmCompile + dependsOn(compileKotlinTask) + +// compileKotlinTask.source(file("src/main/java9")) + options.compilerArgs.add("-Xlint:-requires-transitive-automatic") + + // Patch the compileKotlinJvm output classes into the compilation so exporting packages works correctly. + options.compilerArgs.addAll( + listOf( + "--patch-module", + "$moduleName=${compileKotlinTask.destinationDirectory.get().asFile}", + ), + ) + + classpath = compileKotlinTask.libraries + modularity.inferModulePath.set(true) + } +} diff --git a/mockwebserver-deprecated/build.gradle.kts b/mockwebserver-deprecated/build.gradle.kts index 76ecee9b654f..5b2e1601cadf 100644 --- a/mockwebserver-deprecated/build.gradle.kts +++ b/mockwebserver-deprecated/build.gradle.kts @@ -8,11 +8,7 @@ plugins { id("binary-compatibility-validator") } -tasks.jar { - manifest { - attributes("Automatic-Module-Name" to "okhttp3.mockwebserver") - } -} +project.applyJavaModules("okhttp3.mockwebserver") dependencies { "friendsApi"(projects.okhttp) diff --git a/mockwebserver-deprecated/src/main/java9/module-info.java b/mockwebserver-deprecated/src/main/java9/module-info.java new file mode 100644 index 000000000000..58c21ed92809 --- /dev/null +++ b/mockwebserver-deprecated/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module okhttp3.mockwebserver { + requires okhttp3; + exports okhttp3.mockwebserver; +} diff --git a/mockwebserver-junit4/build.gradle.kts b/mockwebserver-junit4/build.gradle.kts index adc6c3e15ae4..42c260db6206 100644 --- a/mockwebserver-junit4/build.gradle.kts +++ b/mockwebserver-junit4/build.gradle.kts @@ -8,11 +8,7 @@ plugins { id("binary-compatibility-validator") } -tasks.jar { - manifest { - attributes("Automatic-Module-Name" to "mockwebserver3.junit4") - } -} +project.applyJavaModules("mockwebserver3.junit4") dependencies { api(projects.okhttp) diff --git a/mockwebserver-junit4/src/main/java9/module-info.java b/mockwebserver-junit4/src/main/java9/module-info.java new file mode 100644 index 000000000000..3d8dfb953024 --- /dev/null +++ b/mockwebserver-junit4/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module mockwebserver3.junit4 { + requires okhttp3; + exports mockwebserver3.junit4; +} diff --git a/mockwebserver-junit5/build.gradle.kts b/mockwebserver-junit5/build.gradle.kts index 0dac973bdb9f..d7ded94d5d16 100644 --- a/mockwebserver-junit5/build.gradle.kts +++ b/mockwebserver-junit5/build.gradle.kts @@ -8,12 +8,9 @@ plugins { id("binary-compatibility-validator") } +project.applyJavaModules("mockwebserver3.junit5") + tasks { - jar { - manifest { - attributes("Automatic-Module-Name" to "mockwebserver3.junit5") - } - } test { useJUnitPlatform() systemProperty("junit.jupiter.extensions.autodetection.enabled", "true") diff --git a/mockwebserver-junit5/src/main/java9/module-info.java b/mockwebserver-junit5/src/main/java9/module-info.java new file mode 100644 index 000000000000..9395144f6393 --- /dev/null +++ b/mockwebserver-junit5/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module mockwebserver3.junit5 { + requires okhttp3; + opens mockwebserver3.junit5.internal; +} diff --git a/mockwebserver/build.gradle.kts b/mockwebserver/build.gradle.kts index aea7d950abc4..4c9d23661e4d 100644 --- a/mockwebserver/build.gradle.kts +++ b/mockwebserver/build.gradle.kts @@ -8,11 +8,7 @@ plugins { id("binary-compatibility-validator") } -tasks.jar { - manifest { - attributes("Automatic-Module-Name" to "mockwebserver3") - } -} +project.applyJavaModules("mockwebserver3") dependencies { "friendsApi"(projects.okhttp) diff --git a/mockwebserver/src/main/java9/module-info.java b/mockwebserver/src/main/java9/module-info.java new file mode 100644 index 000000000000..bbca39e16606 --- /dev/null +++ b/mockwebserver/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module mockwebserver3 { + requires okhttp3; + exports mockwebserver3; +} diff --git a/okcurl/build.gradle.kts b/okcurl/build.gradle.kts index b1d358d87793..519df1a7daf3 100644 --- a/okcurl/build.gradle.kts +++ b/okcurl/build.gradle.kts @@ -1,6 +1,8 @@ import com.vanniktech.maven.publish.JavadocJar import com.vanniktech.maven.publish.KotlinJvm import org.graalvm.buildtools.gradle.dsl.GraalVMExtension +import org.jetbrains.kotlin.gradle.dsl.jvm.JvmTargetValidationMode +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension plugins { diff --git a/okhttp-brotli/build.gradle.kts b/okhttp-brotli/build.gradle.kts index 69922d9b36e4..ea8213738ec1 100644 --- a/okhttp-brotli/build.gradle.kts +++ b/okhttp-brotli/build.gradle.kts @@ -10,10 +10,11 @@ plugins { project.applyOsgi( "Export-Package: okhttp3.brotli", - "Automatic-Module-Name: okhttp3.brotli", "Bundle-SymbolicName: com.squareup.okhttp3.brotli" ) +project.applyJavaModules("okhttp3.brotli") + dependencies { api(projects.okhttp) api(libs.brotli.dec) diff --git a/okhttp-brotli/src/main/java9/module-info.java b/okhttp-brotli/src/main/java9/module-info.java new file mode 100644 index 000000000000..3e1fd23895b1 --- /dev/null +++ b/okhttp-brotli/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module okhttp3.brotli { + requires okhttp3; + exports okhttp3.brotli; +} diff --git a/okhttp-coroutines/build.gradle.kts b/okhttp-coroutines/build.gradle.kts index 3c96b52c9d3e..c6ed8a804bb8 100644 --- a/okhttp-coroutines/build.gradle.kts +++ b/okhttp-coroutines/build.gradle.kts @@ -10,10 +10,11 @@ plugins { project.applyOsgi( "Export-Package: okhttp3.coroutines", - "Automatic-Module-Name: okhttp3.coroutines", "Bundle-SymbolicName: com.squareup.okhttp3.coroutines" ) +project.applyJavaModules("okhttp3.coroutines") + dependencies { api(projects.okhttp) implementation(libs.kotlinx.coroutines.core) diff --git a/okhttp-coroutines/src/main/java9/module-info.java b/okhttp-coroutines/src/main/java9/module-info.java new file mode 100644 index 000000000000..f9aa3b8a8855 --- /dev/null +++ b/okhttp-coroutines/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module okhttp3.coroutines { + requires okhttp3; + exports okhttp3.coroutines; +} diff --git a/okhttp-dnsoverhttps/build.gradle.kts b/okhttp-dnsoverhttps/build.gradle.kts index 818c8c9d63ae..58d963967dc9 100644 --- a/okhttp-dnsoverhttps/build.gradle.kts +++ b/okhttp-dnsoverhttps/build.gradle.kts @@ -10,10 +10,11 @@ plugins { project.applyOsgi( "Export-Package: okhttp3.dnsoverhttps", - "Automatic-Module-Name: okhttp3.dnsoverhttps", "Bundle-SymbolicName: com.squareup.okhttp3.dnsoverhttps" ) +project.applyJavaModules("okhttp3.dnsoverhttps") + dependencies { "friendsApi"(projects.okhttp) compileOnly(libs.findbugs.jsr305) diff --git a/okhttp-dnsoverhttps/src/main/java9/module-info.java b/okhttp-dnsoverhttps/src/main/java9/module-info.java new file mode 100644 index 000000000000..3bf55cbf82c2 --- /dev/null +++ b/okhttp-dnsoverhttps/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module okhttp3.dnsoverhttps { + requires okhttp3; + exports okhttp3.dnsoverhttps; +} diff --git a/okhttp-java-net-cookiejar/build.gradle.kts b/okhttp-java-net-cookiejar/build.gradle.kts index 43a465412063..e4dea35a7e65 100644 --- a/okhttp-java-net-cookiejar/build.gradle.kts +++ b/okhttp-java-net-cookiejar/build.gradle.kts @@ -10,10 +10,11 @@ plugins { project.applyOsgi( "Export-Package: okhttp3.java.net.cookiejar", - "Automatic-Module-Name: okhttp3.java.net.cookiejar", "Bundle-SymbolicName: com.squareup.okhttp3.java.net.cookiejar" ) +project.applyJavaModules("okhttp3.java.net.cookiejar") + dependencies { "friendsApi"(projects.okhttp) compileOnly(libs.findbugs.jsr305) diff --git a/okhttp-java-net-cookiejar/src/main/java9/module-info.java b/okhttp-java-net-cookiejar/src/main/java9/module-info.java new file mode 100644 index 000000000000..4370bdf653e9 --- /dev/null +++ b/okhttp-java-net-cookiejar/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module okhttp3.java.net.cookiejar { + requires okhttp3; + exports okhttp3.java.net.cookiejar; +} diff --git a/okhttp-logging-interceptor/build.gradle.kts b/okhttp-logging-interceptor/build.gradle.kts index 23308c9083c3..abaaeb5ceed4 100644 --- a/okhttp-logging-interceptor/build.gradle.kts +++ b/okhttp-logging-interceptor/build.gradle.kts @@ -10,10 +10,11 @@ plugins { project.applyOsgi( "Export-Package: okhttp3.logging", - "Automatic-Module-Name: okhttp3.logging", "Bundle-SymbolicName: com.squareup.okhttp3.logging" ) +project.applyJavaModules("okhttp3.logging") + dependencies { "friendsApi"(projects.okhttp) compileOnly(libs.findbugs.jsr305) diff --git a/okhttp-logging-interceptor/src/main/java9/module-info.java b/okhttp-logging-interceptor/src/main/java9/module-info.java new file mode 100644 index 000000000000..f8c06849fca0 --- /dev/null +++ b/okhttp-logging-interceptor/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module okhttp3.logging { + requires okhttp3; + exports okhttp3.logging; +} diff --git a/okhttp-sse/build.gradle.kts b/okhttp-sse/build.gradle.kts index dedeeb4121ea..8920e7e046e2 100644 --- a/okhttp-sse/build.gradle.kts +++ b/okhttp-sse/build.gradle.kts @@ -10,10 +10,11 @@ plugins { project.applyOsgi( "Export-Package: okhttp3.sse", - "Automatic-Module-Name: okhttp3.sse", "Bundle-SymbolicName: com.squareup.okhttp3.sse" ) +project.applyJavaModules("okhttp3.sse") + dependencies { api(projects.okhttp) compileOnly(libs.findbugs.jsr305) diff --git a/okhttp-sse/src/main/java9/module-info.java b/okhttp-sse/src/main/java9/module-info.java new file mode 100644 index 000000000000..8b99bdda31c6 --- /dev/null +++ b/okhttp-sse/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module okhttp3.sse { + requires okhttp3; + exports okhttp3.sse; +} diff --git a/okhttp-tls/build.gradle.kts b/okhttp-tls/build.gradle.kts index 9ddcd90063c8..2c6f1b5e1fc4 100644 --- a/okhttp-tls/build.gradle.kts +++ b/okhttp-tls/build.gradle.kts @@ -11,10 +11,11 @@ plugins { project.applyOsgi( "Export-Package: okhttp3.tls", - "Automatic-Module-Name: okhttp3.tls", "Bundle-SymbolicName: com.squareup.okhttp3.tls" ) +project.applyJavaModules("okhttp3.tls") + dependencies { api(libs.squareup.okio) "friendsImplementation"(projects.okhttp) diff --git a/okhttp-tls/src/main/java9/module-info.java b/okhttp-tls/src/main/java9/module-info.java new file mode 100644 index 000000000000..76f003d651a2 --- /dev/null +++ b/okhttp-tls/src/main/java9/module-info.java @@ -0,0 +1,4 @@ +module okhttp3.tls { + requires okhttp3; + exports okhttp3.tls; +} diff --git a/okhttp-urlconnection/build.gradle.kts b/okhttp-urlconnection/build.gradle.kts index dad3b2f09d23..3aae7f54e762 100644 --- a/okhttp-urlconnection/build.gradle.kts +++ b/okhttp-urlconnection/build.gradle.kts @@ -10,11 +10,12 @@ plugins { project.applyOsgi( "Fragment-Host: com.squareup.okhttp3; bundle-version=\"\${range;[==,+);\${version_cleanup;${projects.okhttp.version}}}\"", - "Automatic-Module-Name: okhttp3.urlconnection", "Bundle-SymbolicName: com.squareup.okhttp3.urlconnection", "-removeheaders: Private-Package" ) +project.applyJavaModules("okhttp3.urlconnection") + dependencies { "friendsApi"(projects.okhttp) api(projects.okhttpJavaNetCookiejar) diff --git a/okhttp-urlconnection/src/main/java9/module-info.java b/okhttp-urlconnection/src/main/java9/module-info.java new file mode 100644 index 000000000000..db7ef95c8370 --- /dev/null +++ b/okhttp-urlconnection/src/main/java9/module-info.java @@ -0,0 +1,3 @@ +module okhttp3.urlconnection { + requires okhttp3; +} diff --git a/okhttp/build.gradle.kts b/okhttp/build.gradle.kts index c83d29a6f377..80655f16cc23 100644 --- a/okhttp/build.gradle.kts +++ b/okhttp/build.gradle.kts @@ -3,6 +3,7 @@ import com.vanniktech.maven.publish.JavadocJar import com.vanniktech.maven.publish.KotlinMultiplatform import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile import ru.vyarus.gradle.plugin.animalsniffer.AnimalSniffer import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension import ru.vyarus.gradle.plugin.animalsniffer.util.TargetType @@ -214,6 +215,68 @@ android { } } +// From https://github.com/Kotlin/kotlinx-atomicfu/blob/master/atomicfu/build.gradle.kts +val compileJavaModuleInfo by tasks.registering(JavaCompile::class) { + val moduleName = "okhttp3" + val compilation = kotlin.targets["jvm"].compilations["main"] + val compileKotlinTask = compilation.compileTaskProvider.get() as KotlinJvmCompile + val targetDir = compileKotlinTask.destinationDirectory.dir("../java9") + val sourceDir = file("src/jvmMain/java9/") + + // Use a Java 11 compiler for the module info. + javaCompiler.set(project.javaToolchains.compilerFor { languageVersion.set(JavaLanguageVersion.of(11)) }) + + // Always compile kotlin classes before the module descriptor. + dependsOn(compileKotlinTask) + + // Add the module-info source file. + source(sourceDir) + + // Also add the module-info.java source file to the Kotlin compile task. + // The Kotlin compiler will parse and check module dependencies, + // but it currently won't compile to a module-info.class file. + // Note that module checking only works on JDK 9+, + // because the JDK built-in base modules are not available in earlier versions. + val javaVersion = compileKotlinTask.kotlinJavaToolchain.javaVersion.getOrNull() + when { + javaVersion?.isJava9Compatible == true -> { + logger.info("Module-info checking is enabled; $compileKotlinTask is compiled using Java $javaVersion") + compileKotlinTask.source(sourceDir) + } + + else -> { + logger.info("Module-info checking is disabled") + } + } + // Set the task outputs and destination dir + outputs.dir(targetDir) + destinationDirectory.set(targetDir) + + // Configure JVM compatibility + sourceCompatibility = JavaVersion.VERSION_1_9.toString() + targetCompatibility = JavaVersion.VERSION_1_9.toString() + + // Set the Java release version. + options.release.set(9) + + // Ignore warnings about using 'requires transitive' on automatic modules. + // not needed when compiling with recent JDKs, e.g. 17 + options.compilerArgs.add("-Xlint:-requires-transitive-automatic") + + // Patch the compileKotlinJvm output classes into the compilation so exporting packages works correctly. + options.compilerArgs.addAll( + listOf( + "--patch-module", + "$moduleName=${compileKotlinTask.destinationDirectory.get().asFile}" + ) + ) + + // Use the classpath of the compileKotlinJvm task. + // Also, ensure that the module path is used instead of the classpath. + classpath = compileKotlinTask.libraries + modularity.inferModulePath.set(true) +} + // Call the convention when the task has finished, to modify the jar to contain OSGi metadata. tasks.named("jvmJar").configure { // Disable to unblock Kotlin bump @@ -221,7 +284,7 @@ tasks.named("jvmJar").configure { manifest { attributes( - "Automatic-Module-Name" to "okhttp3", + "Multi-Release" to true, "Bundle-ManifestVersion" to "okhttp3", "Bundle-Name" to "com.squareup.okhttp3", "Bundle-SymbolicName" to "com.squareup.okhttp3", @@ -232,6 +295,10 @@ tasks.named("jvmJar").configure { ) } + from(compileJavaModuleInfo.get().destinationDirectory) { + into("META-INF/versions/9/") + } + // val bundleExtension = extensions.create( // BundleTaskExtension.NAME, // BundleTaskExtension::class.java, diff --git a/okhttp/src/jvmMain/java9/module-info.java b/okhttp/src/jvmMain/java9/module-info.java new file mode 100644 index 000000000000..cbb6cf4cddf3 --- /dev/null +++ b/okhttp/src/jvmMain/java9/module-info.java @@ -0,0 +1,8 @@ +module okhttp3 { + requires transitive kotlin.stdlib; + requires transitive okio; + exports okhttp3; + opens okhttp3.internal; + opens okhttp3.internal.platform; + opens okhttp3.internal.http; +} From ab042de2cebece0850fb268feec9ed4075700ef1 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 11 May 2025 16:06:16 +0100 Subject: [PATCH 02/24] Fix android tests --- android-test/build.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android-test/build.gradle.kts b/android-test/build.gradle.kts index 93d3737fbc82..ad8491a68a21 100644 --- a/android-test/build.gradle.kts +++ b/android-test/build.gradle.kts @@ -53,7 +53,8 @@ android { "META-INF/LICENSE.md", "META-INF/LICENSE-notice.md", "README.txt", - "org/bouncycastle/LICENSE" + "org/bouncycastle/LICENSE", + "META-INF/versions/9/OSGI-INF/MANIFEST.MF" ) } From 879bf1ae9bb7b5a852ba83ab9565c06f000a6e33 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 11 May 2025 16:09:44 +0100 Subject: [PATCH 03/24] document todo --- buildSrc/src/main/kotlin/JavaModules.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/buildSrc/src/main/kotlin/JavaModules.kt b/buildSrc/src/main/kotlin/JavaModules.kt index 645ff62e6cec..29b8a75003dc 100644 --- a/buildSrc/src/main/kotlin/JavaModules.kt +++ b/buildSrc/src/main/kotlin/JavaModules.kt @@ -36,7 +36,9 @@ fun Project.applyJavaModules( val compileKotlinTask = tasks.getByName("compileKotlin") as KotlinJvmCompile dependsOn(compileKotlinTask) + // TODO enable this so kotlin compile validates the module-info // compileKotlinTask.source(file("src/main/java9")) + options.compilerArgs.add("-Xlint:-requires-transitive-automatic") // Patch the compileKotlinJvm output classes into the compilation so exporting packages works correctly. From 69df1528522c0f31b3a9e6c2d2e3c8a5a6b93de6 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 11 May 2025 16:32:04 +0100 Subject: [PATCH 04/24] Validate more modules --- buildSrc/src/main/kotlin/JavaModules.kt | 6 ++++-- .../src/main/java9/module-info.java | 1 + mockwebserver-junit4/build.gradle.kts | 2 +- mockwebserver-junit4/src/main/java9/module-info.java | 1 + mockwebserver-junit5/build.gradle.kts | 2 +- mockwebserver/src/main/java9/module-info.java | 1 + okhttp/build.gradle.kts | 3 ++- okhttp/src/jvmMain/java9/module-info.java | 10 +++++++--- 8 files changed, 18 insertions(+), 8 deletions(-) diff --git a/buildSrc/src/main/kotlin/JavaModules.kt b/buildSrc/src/main/kotlin/JavaModules.kt index 29b8a75003dc..dfcba06d957f 100644 --- a/buildSrc/src/main/kotlin/JavaModules.kt +++ b/buildSrc/src/main/kotlin/JavaModules.kt @@ -25,6 +25,7 @@ fun Project.applyJavaModules( moduleName: String, defaultVersion: Int = 8, javaModuleVersion: Int = 9, + enableValidation: Boolean = true, ) { plugins.apply("me.champeau.mrjar") @@ -36,8 +37,9 @@ fun Project.applyJavaModules( val compileKotlinTask = tasks.getByName("compileKotlin") as KotlinJvmCompile dependsOn(compileKotlinTask) - // TODO enable this so kotlin compile validates the module-info -// compileKotlinTask.source(file("src/main/java9")) + if (enableValidation) { + compileKotlinTask.source(file("src/main/java9")) + } options.compilerArgs.add("-Xlint:-requires-transitive-automatic") diff --git a/mockwebserver-deprecated/src/main/java9/module-info.java b/mockwebserver-deprecated/src/main/java9/module-info.java index 58c21ed92809..4027da9a1f1e 100644 --- a/mockwebserver-deprecated/src/main/java9/module-info.java +++ b/mockwebserver-deprecated/src/main/java9/module-info.java @@ -1,4 +1,5 @@ module okhttp3.mockwebserver { requires okhttp3; exports okhttp3.mockwebserver; + requires java.logging; } diff --git a/mockwebserver-junit4/build.gradle.kts b/mockwebserver-junit4/build.gradle.kts index 42c260db6206..55eebff7886b 100644 --- a/mockwebserver-junit4/build.gradle.kts +++ b/mockwebserver-junit4/build.gradle.kts @@ -8,7 +8,7 @@ plugins { id("binary-compatibility-validator") } -project.applyJavaModules("mockwebserver3.junit4") +project.applyJavaModules("mockwebserver3.junit4", enableValidation = false) dependencies { api(projects.okhttp) diff --git a/mockwebserver-junit4/src/main/java9/module-info.java b/mockwebserver-junit4/src/main/java9/module-info.java index 3d8dfb953024..767bb5fa6a61 100644 --- a/mockwebserver-junit4/src/main/java9/module-info.java +++ b/mockwebserver-junit4/src/main/java9/module-info.java @@ -1,4 +1,5 @@ module mockwebserver3.junit4 { requires okhttp3; exports mockwebserver3.junit4; + requires java.logging; } diff --git a/mockwebserver-junit5/build.gradle.kts b/mockwebserver-junit5/build.gradle.kts index d7ded94d5d16..2d3f434271a1 100644 --- a/mockwebserver-junit5/build.gradle.kts +++ b/mockwebserver-junit5/build.gradle.kts @@ -8,7 +8,7 @@ plugins { id("binary-compatibility-validator") } -project.applyJavaModules("mockwebserver3.junit5") +project.applyJavaModules("mockwebserver3.junit5", enableValidation = false) tasks { test { diff --git a/mockwebserver/src/main/java9/module-info.java b/mockwebserver/src/main/java9/module-info.java index bbca39e16606..82bb585408b9 100644 --- a/mockwebserver/src/main/java9/module-info.java +++ b/mockwebserver/src/main/java9/module-info.java @@ -1,4 +1,5 @@ module mockwebserver3 { requires okhttp3; exports mockwebserver3; + requires java.logging; } diff --git a/okhttp/build.gradle.kts b/okhttp/build.gradle.kts index 80655f16cc23..83a4ec9005aa 100644 --- a/okhttp/build.gradle.kts +++ b/okhttp/build.gradle.kts @@ -241,7 +241,8 @@ val compileJavaModuleInfo by tasks.registering(JavaCompile::class) { when { javaVersion?.isJava9Compatible == true -> { logger.info("Module-info checking is enabled; $compileKotlinTask is compiled using Java $javaVersion") - compileKotlinTask.source(sourceDir) + // Disabled as this module can't see the others in this build for some reason +// compileKotlinTask.source(sourceDir) } else -> { diff --git a/okhttp/src/jvmMain/java9/module-info.java b/okhttp/src/jvmMain/java9/module-info.java index cbb6cf4cddf3..5003dd62ce8b 100644 --- a/okhttp/src/jvmMain/java9/module-info.java +++ b/okhttp/src/jvmMain/java9/module-info.java @@ -2,7 +2,11 @@ requires transitive kotlin.stdlib; requires transitive okio; exports okhttp3; - opens okhttp3.internal; - opens okhttp3.internal.platform; - opens okhttp3.internal.http; + exports okhttp3.internal to okhttp3.logging, okhttp3.sse, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.coroutines, okhttp3.tls; + exports okhttp3.internal.platform to okhttp3.logging, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.tls; + exports okhttp3.internal.http to okhttp3.logging, okhttp3.brotli, mockwebserver3; + exports okhttp3.internal.http2 to mockwebserver3, okhttp3.mockwebserver; + exports okhttp3.internal.concurrent to mockwebserver3, okhttp3.mockwebserver; + exports okhttp3.internal.ws to mockwebserver3, okhttp3.mockwebserver; + exports okhttp3.internal.publicsuffix to okhttp3.dnsoverhttps; } From ac24e725cbda9dc0f5143aeb33a4e961608c6755 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 11 May 2025 17:28:40 +0100 Subject: [PATCH 05/24] Fix --- okcurl/build.gradle.kts | 2 -- 1 file changed, 2 deletions(-) diff --git a/okcurl/build.gradle.kts b/okcurl/build.gradle.kts index 519df1a7daf3..b1d358d87793 100644 --- a/okcurl/build.gradle.kts +++ b/okcurl/build.gradle.kts @@ -1,8 +1,6 @@ import com.vanniktech.maven.publish.JavadocJar import com.vanniktech.maven.publish.KotlinJvm import org.graalvm.buildtools.gradle.dsl.GraalVMExtension -import org.jetbrains.kotlin.gradle.dsl.jvm.JvmTargetValidationMode -import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension plugins { From ce79429774ab8dc51720950197c77eb9ae8c3a1a Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 11 May 2025 17:44:41 +0100 Subject: [PATCH 06/24] Add a test module compiling using Java modules --- build.gradle.kts | 2 +- okhttp-module-tests/build.gradle.kts | 47 +++++++++++++++++++ .../src/main/java/module-info.java | 4 ++ .../kotlin/okhttp3/modules/OkHttpCaller.kt | 36 ++++++++++++++ .../kotlin/okhttp3/modules/JavaModuleTest.kt | 27 +++++++++++ settings.gradle.kts | 1 + 6 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 okhttp-module-tests/build.gradle.kts create mode 100644 okhttp-module-tests/src/main/java/module-info.java create mode 100644 okhttp-module-tests/src/main/kotlin/okhttp3/modules/OkHttpCaller.kt create mode 100644 okhttp-module-tests/src/test/kotlin/okhttp3/modules/JavaModuleTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index f9f273329935..96f844696328 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension import java.net.URI @@ -92,6 +91,7 @@ subprojects { if (project.name == "regression-test") return@subprojects if (project.name == "android-test-app") return@subprojects if (project.name == "container-tests") return@subprojects + if (project.name == "okhttp-module-tests") return@subprojects apply(plugin = "checkstyle") apply(plugin = "ru.vyarus.animalsniffer") diff --git a/okhttp-module-tests/build.gradle.kts b/okhttp-module-tests/build.gradle.kts new file mode 100644 index 000000000000..6353bb210078 --- /dev/null +++ b/okhttp-module-tests/build.gradle.kts @@ -0,0 +1,47 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") +} + +dependencies { + implementation(projects.okhttp) + implementation(projects.okhttpBrotli) + implementation(projects.okhttpCoroutines) + implementation(projects.okhttpDnsoverhttps) + implementation(projects.loggingInterceptor) + implementation(projects.okhttpSse) + implementation(projects.okhttpTls) + implementation(projects.okhttpUrlconnection) + + testImplementation(projects.okhttpTestingSupport) + testImplementation(libs.junit) + testImplementation(libs.kotlin.test.common) + testImplementation(libs.kotlin.test.junit) + testImplementation(libs.assertk) + + testRuntimeOnly(libs.junit.jupiter.engine) + testRuntimeOnly(libs.junit.platform.launcher) +} + +tasks.withType { + useJUnitPlatform() + systemProperty("junit.jupiter.extensions.autodetection.enabled", "true") +} + +val testJavaVersion = System.getProperty("test.java.version", "21").toInt() + +java { + sourceCompatibility = JavaVersion.toVersion(testJavaVersion) + targetCompatibility = JavaVersion.toVersion(testJavaVersion) + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } +} + +tasks.withType { + compilerOptions { + jvmTarget.set(JvmTarget.fromTarget(testJavaVersion.toString())) + } +} diff --git a/okhttp-module-tests/src/main/java/module-info.java b/okhttp-module-tests/src/main/java/module-info.java new file mode 100644 index 000000000000..a43fecc5b0f2 --- /dev/null +++ b/okhttp-module-tests/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module okhttp3.module.test { + requires okhttp3; + requires okhttp3.logging; +} diff --git a/okhttp-module-tests/src/main/kotlin/okhttp3/modules/OkHttpCaller.kt b/okhttp-module-tests/src/main/kotlin/okhttp3/modules/OkHttpCaller.kt new file mode 100644 index 000000000000..bcb55e87f9f3 --- /dev/null +++ b/okhttp-module-tests/src/main/kotlin/okhttp3/modules/OkHttpCaller.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 Block, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package okhttp3.modules + +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.logging.LoggingEventListener + +/** + * Just checking compilation works + */ +object OkHttpCaller { + fun callOkHttp() { + val client = + OkHttpClient + .Builder() + .eventListenerFactory(LoggingEventListener.Factory()) + .build() + client.newCall(Request("https://square.com".toHttpUrl())) + } +} diff --git a/okhttp-module-tests/src/test/kotlin/okhttp3/modules/JavaModuleTest.kt b/okhttp-module-tests/src/test/kotlin/okhttp3/modules/JavaModuleTest.kt new file mode 100644 index 000000000000..aee0c6fd443b --- /dev/null +++ b/okhttp-module-tests/src/test/kotlin/okhttp3/modules/JavaModuleTest.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2025 Block, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package okhttp3.modules + +import org.junit.jupiter.api.Test + +class JavaModuleTest { + @Test + fun testVisibility() { + // Just check we can run code that depends on OkHttp types + OkHttpCaller.callOkHttp() + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 03aa4ef354e8..5fb5a4409123 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,6 +37,7 @@ include(":okhttp-hpacktests") include(":okhttp-idna-mapping-table") include(":okhttp-java-net-cookiejar") include(":okhttp-logging-interceptor") +include(":okhttp-module-tests") include(":okhttp-osgi-tests") include(":okhttp-sse") include(":okhttp-testing-support") From fe7e54924b7425a617f89df5e54689bef63fe9a5 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 11 May 2025 20:46:30 +0100 Subject: [PATCH 07/24] Avoid running module tests on JDK 8 --- okhttp-module-tests/build.gradle.kts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/okhttp-module-tests/build.gradle.kts b/okhttp-module-tests/build.gradle.kts index 6353bb210078..439bf6bd3949 100644 --- a/okhttp-module-tests/build.gradle.kts +++ b/okhttp-module-tests/build.gradle.kts @@ -25,16 +25,19 @@ dependencies { testRuntimeOnly(libs.junit.platform.launcher) } +val testJavaVersion = System.getProperty("test.java.version", "21").toInt() +val compileJavaVersion = testJavaVersion.coerceAtLeast(9) + tasks.withType { useJUnitPlatform() systemProperty("junit.jupiter.extensions.autodetection.enabled", "true") -} -val testJavaVersion = System.getProperty("test.java.version", "21").toInt() + enabled = testJavaVersion > 8 +} java { - sourceCompatibility = JavaVersion.toVersion(testJavaVersion) - targetCompatibility = JavaVersion.toVersion(testJavaVersion) + sourceCompatibility = JavaVersion.toVersion(compileJavaVersion) + targetCompatibility = JavaVersion.toVersion(compileJavaVersion) toolchain { languageVersion.set(JavaLanguageVersion.of(21)) } @@ -42,6 +45,6 @@ java { tasks.withType { compilerOptions { - jvmTarget.set(JvmTarget.fromTarget(testJavaVersion.toString())) + jvmTarget.set(JvmTarget.fromTarget(compileJavaVersion.toString())) } } From a828dc74b2d55208443d6a1c47f66b55807cffe4 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 11 May 2025 21:45:24 +0100 Subject: [PATCH 08/24] Add a jlink run task to demonstrate java modules --- okhttp-module-tests/build.gradle.kts | 45 ++++++++++++------- .../src/main/java/module-info.java | 4 +- .../src/main/java/okhttp3/modules/Main.java | 29 ++++++++++++ .../okhttp3/modules/OkHttpCaller.java} | 25 +++++------ okhttp/src/jvmMain/java9/module-info.java | 1 + 5 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 okhttp-module-tests/src/main/java/okhttp3/modules/Main.java rename okhttp-module-tests/src/main/{kotlin/okhttp3/modules/OkHttpCaller.kt => java/okhttp3/modules/OkHttpCaller.java} (59%) diff --git a/okhttp-module-tests/build.gradle.kts b/okhttp-module-tests/build.gradle.kts index 439bf6bd3949..3793f14f5114 100644 --- a/okhttp-module-tests/build.gradle.kts +++ b/okhttp-module-tests/build.gradle.kts @@ -2,18 +2,15 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") + id("java") + id("application") + id("com.github.iherasymenko.jlink") version "0.7" + id("org.gradlex.extra-java-module-info") version "1.12" } dependencies { implementation(projects.okhttp) - implementation(projects.okhttpBrotli) - implementation(projects.okhttpCoroutines) - implementation(projects.okhttpDnsoverhttps) implementation(projects.loggingInterceptor) - implementation(projects.okhttpSse) - implementation(projects.okhttpTls) - implementation(projects.okhttpUrlconnection) testImplementation(projects.okhttpTestingSupport) testImplementation(libs.junit) @@ -25,26 +22,42 @@ dependencies { testRuntimeOnly(libs.junit.platform.launcher) } +application { + mainClass = "okhttp3.modules.Main" + mainModule = "okhttp3.modules" +} + +extraJavaModuleInfo { + module("org.jetbrains:annotations", "org.jetbrains.annotations") { + exportAllPackages() + } + module("com.squareup.okio:okio-jvm", "okio") { + exportAllPackages() + requires("kotlin.stdlib") + requires("java.logging") + } + module("com.squareup.okio:okio", "okio") { + exportAllPackages() + } +} + val testJavaVersion = System.getProperty("test.java.version", "21").toInt() -val compileJavaVersion = testJavaVersion.coerceAtLeast(9) tasks.withType { useJUnitPlatform() systemProperty("junit.jupiter.extensions.autodetection.enabled", "true") enabled = testJavaVersion > 8 + + javaLauncher.set(javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(testJavaVersion)) + }) } java { - sourceCompatibility = JavaVersion.toVersion(compileJavaVersion) - targetCompatibility = JavaVersion.toVersion(compileJavaVersion) + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 toolchain { languageVersion.set(JavaLanguageVersion.of(21)) } } - -tasks.withType { - compilerOptions { - jvmTarget.set(JvmTarget.fromTarget(compileJavaVersion.toString())) - } -} diff --git a/okhttp-module-tests/src/main/java/module-info.java b/okhttp-module-tests/src/main/java/module-info.java index a43fecc5b0f2..0c9cd1356026 100644 --- a/okhttp-module-tests/src/main/java/module-info.java +++ b/okhttp-module-tests/src/main/java/module-info.java @@ -1,4 +1,6 @@ -module okhttp3.module.test { +module okhttp3.modules { requires okhttp3; requires okhttp3.logging; + requires jdk.crypto.ec; + exports okhttp3.modules; } diff --git a/okhttp-module-tests/src/main/java/okhttp3/modules/Main.java b/okhttp-module-tests/src/main/java/okhttp3/modules/Main.java new file mode 100644 index 000000000000..9900a9a45f0a --- /dev/null +++ b/okhttp-module-tests/src/main/java/okhttp3/modules/Main.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2025 Block, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package okhttp3.modules; + +import okhttp3.Call; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) throws IOException { + Call call = OkHttpCaller.callOkHttp(); + + System.out.println(call.execute().body().string()); + } +} diff --git a/okhttp-module-tests/src/main/kotlin/okhttp3/modules/OkHttpCaller.kt b/okhttp-module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java similarity index 59% rename from okhttp-module-tests/src/main/kotlin/okhttp3/modules/OkHttpCaller.kt rename to okhttp-module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java index bcb55e87f9f3..8aa68429a122 100644 --- a/okhttp-module-tests/src/main/kotlin/okhttp3/modules/OkHttpCaller.kt +++ b/okhttp-module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java @@ -14,23 +14,22 @@ * limitations under the License. */ -package okhttp3.modules +package okhttp3.modules; -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.logging.LoggingEventListener +import okhttp3.Call; +import okhttp3.OkHttpClient; +import okhttp3.Request; +//import okhttp3.logging.LoggingEventListener; /** * Just checking compilation works */ -object OkHttpCaller { - fun callOkHttp() { - val client = - OkHttpClient - .Builder() - .eventListenerFactory(LoggingEventListener.Factory()) - .build() - client.newCall(Request("https://square.com".toHttpUrl())) +public class OkHttpCaller { + public static Call callOkHttp() { + OkHttpClient client = new OkHttpClient + .Builder() +// .eventListenerFactory(LoggingEventListener.Factory()) + .build(); + return client.newCall(new Request.Builder().url("https://square.com/robots.txt").build()); } } diff --git a/okhttp/src/jvmMain/java9/module-info.java b/okhttp/src/jvmMain/java9/module-info.java index 5003dd62ce8b..c215e128d09c 100644 --- a/okhttp/src/jvmMain/java9/module-info.java +++ b/okhttp/src/jvmMain/java9/module-info.java @@ -1,6 +1,7 @@ module okhttp3 { requires transitive kotlin.stdlib; requires transitive okio; + requires java.logging; exports okhttp3; exports okhttp3.internal to okhttp3.logging, okhttp3.sse, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.coroutines, okhttp3.tls; exports okhttp3.internal.platform to okhttp3.logging, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.tls; From f1a2f03b431b3d2f58a01567dbe159017cec4d1d Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Mon, 16 Jun 2025 17:41:06 +0300 Subject: [PATCH 09/24] Fix version --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 579c33b7cf0f..c48c49a23369 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -30,7 +30,7 @@ dependencies { // Cannot change attributes of configuration ':native-image-tests:compileClasspath' after it has been locked for mutation implementation("biz.aQute.bnd:biz.aQute.bnd.gradle:7.1.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin-api:2.1.20") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin-api:2.1.21") implementation("me.champeau.mrjar:me.champeau.mrjar.gradle.plugin:0.1.1") } From aca50139ad5260c47f145e77128a19ea1ac97cbc Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 21 Jun 2025 11:11:09 +0100 Subject: [PATCH 10/24] Update --- buildSrc/build.gradle.kts | 10 ++--- buildSrc/settings.gradle.kts | 8 ++++ gradle/libs.versions.toml | 2 + okhttp/build.gradle.kts | 76 ++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 579c33b7cf0f..66da41144889 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,13 +24,9 @@ repositories { } dependencies { - // TODO (https://github.com/square/okhttp/issues/8612) we will need a consistent version - // 7.1.0 is used because it avoids this error - // Could not create an instance of type aQute.bnd.gradle.BundleTaskExtension. - // Cannot change attributes of configuration ':native-image-tests:compileClasspath' after it has been locked for mutation - implementation("biz.aQute.bnd:biz.aQute.bnd.gradle:7.1.0") + implementation(libs.gradlePlugin.bnd) - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin-api:2.1.20") + implementation(libs.kotlin.gradle.plugin.api) - implementation("me.champeau.mrjar:me.champeau.mrjar.gradle.plugin:0.1.1") + implementation(libs.gradlePlugin.mrjar) } diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index ae6fdeecb742..677f4940c4c3 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -1 +1,9 @@ rootProject.name = "okhttp-buildSrc" + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a2fa9fce5bc6..e7b997e7cc6a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -57,6 +57,7 @@ gradlePlugin-kotlinSerialization = { module = "org.jetbrains.kotlin:kotlin-seria gradlePlugin-ksp = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" } gradlePlugin-mavenPublish = "com.vanniktech:gradle-maven-publish-plugin:0.32.0" gradlePlugin-mavenSympathy = "io.github.usefulness.maven-sympathy:io.github.usefulness.maven-sympathy.gradle.plugin:0.3.0" +gradlePlugin-mrjar = "me.champeau.mrjar:me.champeau.mrjar.gradle.plugin:0.1.1" gradlePlugin-shadow = "com.gradleup.shadow:shadow-gradle-plugin:8.3.6" gradlePlugin-spotless = "com.diffplug.spotless:spotless-plugin-gradle:7.0.4" hamcrestLibrary = "org.hamcrest:hamcrest-library:3.0" @@ -75,6 +76,7 @@ junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", vers junit-pioneer = "org.junit-pioneer:junit-pioneer:1.9.1" junit5android-core = { module = "de.mannodermaus.junit5:android-test-core", version.ref = "de-mannodermaus-junit5" } junit5android-runner = { module = "de.mannodermaus.junit5:android-test-runner", version.ref = "de-mannodermaus-junit5" } +kotlin-gradle-plugin-api = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin-api", version.ref = "org-jetbrains-kotlin" } kotlin-junit5 = { module = "org.jetbrains.kotlin:kotlin-test-junit5", version.ref = "org-jetbrains-kotlin" } kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "org-jetbrains-kotlin" } kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "org-jetbrains-kotlin" } diff --git a/okhttp/build.gradle.kts b/okhttp/build.gradle.kts index 681edda03dcb..9d56c02f0b64 100644 --- a/okhttp/build.gradle.kts +++ b/okhttp/build.gradle.kts @@ -3,6 +3,7 @@ import com.vanniktech.maven.publish.JavadocJar import com.vanniktech.maven.publish.KotlinMultiplatform import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile import ru.vyarus.gradle.plugin.animalsniffer.AnimalSniffer import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension @@ -225,6 +226,81 @@ project.applyOsgiMultiplatform( "Bundle-SymbolicName: com.squareup.okhttp3", ) +// From https://github.com/Kotlin/kotlinx-atomicfu/blob/master/atomicfu/build.gradle.kts +val compileJavaModuleInfo by tasks.registering(JavaCompile::class) { + val moduleName = "okhttp3" + val compilation = kotlin.targets["jvm"].compilations["main"] + val compileKotlinTask = compilation.compileTaskProvider.get() as KotlinJvmCompile + val targetDir = compileKotlinTask.destinationDirectory.dir("../java9") + val sourceDir = file("src/jvmMain/java9/") + + // Use a Java 11 compiler for the module info. + javaCompiler.set(project.javaToolchains.compilerFor { languageVersion.set(JavaLanguageVersion.of(11)) }) + + // Always compile kotlin classes before the module descriptor. + dependsOn(compileKotlinTask) + + // Add the module-info source file. + source(sourceDir) + + // Also add the module-info.java source file to the Kotlin compile task. + // The Kotlin compiler will parse and check module dependencies, + // but it currently won't compile to a module-info.class file. + // Note that module checking only works on JDK 9+, + // because the JDK built-in base modules are not available in earlier versions. + val javaVersion = compileKotlinTask.kotlinJavaToolchain.javaVersion.getOrNull() + when { + javaVersion?.isJava9Compatible == true -> { + logger.info("Module-info checking is enabled; $compileKotlinTask is compiled using Java $javaVersion") + // Disabled as this module can't see the others in this build for some reason +// compileKotlinTask.source(sourceDir) + } + + else -> { + logger.info("Module-info checking is disabled") + } + } + // Set the task outputs and destination dir + outputs.dir(targetDir) + destinationDirectory.set(targetDir) + + // Configure JVM compatibility + sourceCompatibility = JavaVersion.VERSION_1_9.toString() + targetCompatibility = JavaVersion.VERSION_1_9.toString() + + // Set the Java release version. + options.release.set(9) + + // Ignore warnings about using 'requires transitive' on automatic modules. + // not needed when compiling with recent JDKs, e.g. 17 + options.compilerArgs.add("-Xlint:-requires-transitive-automatic") + + // Patch the compileKotlinJvm output classes into the compilation so exporting packages works correctly. + options.compilerArgs.addAll( + listOf( + "--patch-module", + "$moduleName=${compileKotlinTask.destinationDirectory.get().asFile}" + ) + ) + + // Use the classpath of the compileKotlinJvm task. + // Also, ensure that the module path is used instead of the classpath. + classpath = compileKotlinTask.libraries + modularity.inferModulePath.set(true) +} + +tasks.named("jvmJar").configure { + manifest { + attributes( + "Multi-Release" to true, + ) + } + + from(compileJavaModuleInfo.get().destinationDirectory) { + into("META-INF/versions/9/") + } +} + tasks.named("jvmJar").configure { manifest { attributes( From 0973e8d7a517b5ca8673dc965c09b0b82ab22c2e Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 21 Jun 2025 11:15:13 +0100 Subject: [PATCH 11/24] Remove old comment --- gradle/libs.versions.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e7b997e7cc6a..d69dab2fe4f1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,4 @@ [versions] -# 7.0.0 is JDK 17+ https://github.com/bndtools/bnd/wiki/Changes-in-7.0.0 biz-aQute-bnd = "7.1.0" checkStyle = "10.25.0" com-squareup-moshi = "1.15.2" From 1ba44f1dd4457bf7ab1ad63ddb7de52c29c19ffa Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 12 Jul 2025 17:05:25 +0100 Subject: [PATCH 12/24] Update module test --- build.gradle.kts | 2 +- .../build.gradle.kts | 9 ++-- .../src/main/java/module-info.java | 0 .../src/main/java/okhttp3/modules/Main.java | 0 .../java/okhttp3/modules/OkHttpCaller.java | 0 module-tests/src/test/java/module-info.java | 8 ++++ .../okhttp3/modules/test/JavaModuleTest.java | 44 +++++++++++++++++++ .../kotlin/okhttp3/modules/JavaModuleTest.kt | 27 ------------ settings.gradle.kts | 2 +- 9 files changed, 57 insertions(+), 35 deletions(-) rename {okhttp-module-tests => module-tests}/build.gradle.kts (82%) rename {okhttp-module-tests => module-tests}/src/main/java/module-info.java (100%) rename {okhttp-module-tests => module-tests}/src/main/java/okhttp3/modules/Main.java (100%) rename {okhttp-module-tests => module-tests}/src/main/java/okhttp3/modules/OkHttpCaller.java (100%) create mode 100644 module-tests/src/test/java/module-info.java create mode 100644 module-tests/src/test/java/okhttp3/modules/test/JavaModuleTest.java delete mode 100644 okhttp-module-tests/src/test/kotlin/okhttp3/modules/JavaModuleTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index 57f7b3244037..f7e0eecae996 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -92,7 +92,7 @@ subprojects { if (project.name == "regression-test") return@subprojects if (project.name == "android-test-app") return@subprojects if (project.name == "container-tests") return@subprojects - if (project.name == "okhttp-module-tests") return@subprojects + if (project.name == "module-tests") return@subprojects apply(plugin = "checkstyle") apply(plugin = "ru.vyarus.animalsniffer") diff --git a/okhttp-module-tests/build.gradle.kts b/module-tests/build.gradle.kts similarity index 82% rename from okhttp-module-tests/build.gradle.kts rename to module-tests/build.gradle.kts index 3793f14f5114..aa9254ea9128 100644 --- a/okhttp-module-tests/build.gradle.kts +++ b/module-tests/build.gradle.kts @@ -12,12 +12,10 @@ dependencies { implementation(projects.okhttp) implementation(projects.loggingInterceptor) - testImplementation(projects.okhttpTestingSupport) - testImplementation(libs.junit) - testImplementation(libs.kotlin.test.common) - testImplementation(libs.kotlin.test.junit) - testImplementation(libs.assertk) + testImplementation(projects.okhttp) + testImplementation(projects.loggingInterceptor) + testImplementation(libs.junit.jupiter.api) testRuntimeOnly(libs.junit.jupiter.engine) testRuntimeOnly(libs.junit.platform.launcher) } @@ -45,7 +43,6 @@ val testJavaVersion = System.getProperty("test.java.version", "21").toInt() tasks.withType { useJUnitPlatform() - systemProperty("junit.jupiter.extensions.autodetection.enabled", "true") enabled = testJavaVersion > 8 diff --git a/okhttp-module-tests/src/main/java/module-info.java b/module-tests/src/main/java/module-info.java similarity index 100% rename from okhttp-module-tests/src/main/java/module-info.java rename to module-tests/src/main/java/module-info.java diff --git a/okhttp-module-tests/src/main/java/okhttp3/modules/Main.java b/module-tests/src/main/java/okhttp3/modules/Main.java similarity index 100% rename from okhttp-module-tests/src/main/java/okhttp3/modules/Main.java rename to module-tests/src/main/java/okhttp3/modules/Main.java diff --git a/okhttp-module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java b/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java similarity index 100% rename from okhttp-module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java rename to module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java diff --git a/module-tests/src/test/java/module-info.java b/module-tests/src/test/java/module-info.java new file mode 100644 index 000000000000..67bdb8597b83 --- /dev/null +++ b/module-tests/src/test/java/module-info.java @@ -0,0 +1,8 @@ +module okhttp3.modules.test { + requires okhttp3; + requires okhttp3.logging; + requires jdk.crypto.ec; + requires org.junit.jupiter.api; + requires okhttp3.modules; + opens okhttp3.modules.test to org.junit.platform.commons; +} diff --git a/module-tests/src/test/java/okhttp3/modules/test/JavaModuleTest.java b/module-tests/src/test/java/okhttp3/modules/test/JavaModuleTest.java new file mode 100644 index 000000000000..c81944502c8e --- /dev/null +++ b/module-tests/src/test/java/okhttp3/modules/test/JavaModuleTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2025 Block, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package okhttp3.modules.test; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import okhttp3.modules.OkHttpCaller; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class JavaModuleTest { + @Test + public void testVisibility() { + // Just check we can run code that depends on OkHttp types + OkHttpCaller.callOkHttp(); + } + + @Test + public void testModules() { + Module okHttpModule = OkHttpClient.class.getModule(); + assertEquals("okhttp3", okHttpModule.getName()); + assertTrue(okHttpModule.getPackages().contains("okhttp3")); + + Module loggingInterceptorModule = HttpLoggingInterceptor.class.getModule(); + assertEquals("okhttp3.logging", loggingInterceptorModule.getName()); + assertTrue(loggingInterceptorModule.getPackages().contains("okhttp3.logging")); + } +} diff --git a/okhttp-module-tests/src/test/kotlin/okhttp3/modules/JavaModuleTest.kt b/okhttp-module-tests/src/test/kotlin/okhttp3/modules/JavaModuleTest.kt deleted file mode 100644 index aee0c6fd443b..000000000000 --- a/okhttp-module-tests/src/test/kotlin/okhttp3/modules/JavaModuleTest.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2025 Block, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package okhttp3.modules - -import org.junit.jupiter.api.Test - -class JavaModuleTest { - @Test - fun testVisibility() { - // Just check we can run code that depends on OkHttp types - OkHttpCaller.callOkHttp() - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 3ccbfcf39817..e901b5fce416 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,7 +37,6 @@ include(":okhttp-hpacktests") include(":okhttp-idna-mapping-table") include(":okhttp-java-net-cookiejar") include(":okhttp-logging-interceptor") -include(":okhttp-module-tests") include(":okhttp-osgi-tests") include(":okhttp-sse") include(":okhttp-testing-support") @@ -52,6 +51,7 @@ include(":samples:static-server") include(":samples:tlssurvey") include(":samples:unixdomainsockets") include(":container-tests") +include(":module-tests") project(":okhttp-logging-interceptor").name = "logging-interceptor" From 6a3a64b1b92aaad3b25de8cafc6b8ff5fa4b4649 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 10:18:14 +0100 Subject: [PATCH 13/24] cleanup and document --- README.md | 19 +++++++++++++++++++ buildSrc/src/main/kotlin/JavaModules.kt | 2 ++ mockwebserver-junit4/build.gradle.kts | 2 +- mockwebserver-junit5/build.gradle.kts | 2 +- module-tests/build.gradle.kts | 2 +- .../java/okhttp3/modules/OkHttpCaller.java | 2 +- 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e557fb1a0163..78628e566d3d 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,25 @@ $ ./gradlew okcurl:nativeImage $ ./okcurl/build/graal/okcurl https://httpbin.org/get ``` +Java Modules +------------ + +OkHttp (5.3+) implements Java 9 Modules such that in Java builds. +The list of defined modules is: + +- okhttp3 +- okhttp3.brotli +- okhttp3.coroutines +- okhttp3.dnsoverhttps +- okhttp3.java.net.cookiejar +- okhttp3.logging +- okhttp3.sse +- okhttp3.tls +- okhttp3.urlconnection +- mockwebserver3 +- mockwebserver3.junit4 +- mockwebserver3.junit5 + License ------- diff --git a/buildSrc/src/main/kotlin/JavaModules.kt b/buildSrc/src/main/kotlin/JavaModules.kt index dfcba06d957f..57324670a419 100644 --- a/buildSrc/src/main/kotlin/JavaModules.kt +++ b/buildSrc/src/main/kotlin/JavaModules.kt @@ -41,6 +41,8 @@ fun Project.applyJavaModules( compileKotlinTask.source(file("src/main/java9")) } + // Ignore warnings about using 'requires transitive' on automatic modules. + // not needed when compiling with recent JDKs, e.g. 17 options.compilerArgs.add("-Xlint:-requires-transitive-automatic") // Patch the compileKotlinJvm output classes into the compilation so exporting packages works correctly. diff --git a/mockwebserver-junit4/build.gradle.kts b/mockwebserver-junit4/build.gradle.kts index 55eebff7886b..42c260db6206 100644 --- a/mockwebserver-junit4/build.gradle.kts +++ b/mockwebserver-junit4/build.gradle.kts @@ -8,7 +8,7 @@ plugins { id("binary-compatibility-validator") } -project.applyJavaModules("mockwebserver3.junit4", enableValidation = false) +project.applyJavaModules("mockwebserver3.junit4") dependencies { api(projects.okhttp) diff --git a/mockwebserver-junit5/build.gradle.kts b/mockwebserver-junit5/build.gradle.kts index aa5ebaf77ec6..e99b14b18f72 100644 --- a/mockwebserver-junit5/build.gradle.kts +++ b/mockwebserver-junit5/build.gradle.kts @@ -8,7 +8,7 @@ plugins { id("binary-compatibility-validator") } -project.applyJavaModules("mockwebserver3.junit5", enableValidation = false) +project.applyJavaModules("mockwebserver3.junit5") tasks { test { diff --git a/module-tests/build.gradle.kts b/module-tests/build.gradle.kts index aa9254ea9128..a54f2906e20a 100644 --- a/module-tests/build.gradle.kts +++ b/module-tests/build.gradle.kts @@ -22,7 +22,7 @@ dependencies { application { mainClass = "okhttp3.modules.Main" - mainModule = "okhttp3.modules" + mainModule = "okhttp3.module.tests" } extraJavaModuleInfo { diff --git a/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java b/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java index 8aa68429a122..beb81d1c5fc2 100644 --- a/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java +++ b/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java @@ -28,7 +28,7 @@ public class OkHttpCaller { public static Call callOkHttp() { OkHttpClient client = new OkHttpClient .Builder() -// .eventListenerFactory(LoggingEventListener.Factory()) + .eventListenerFactory(LoggingEventListener.Factory()) .build(); return client.newCall(new Request.Builder().url("https://square.com/robots.txt").build()); } From 2b452f727713860313f4017d066ff9bb6cc9510b Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 10:25:19 +0100 Subject: [PATCH 14/24] suppress module warnings --- mockwebserver-deprecated/src/main/java9/module-info.java | 1 + mockwebserver-junit4/src/main/java9/module-info.java | 1 + mockwebserver-junit5/src/main/java9/module-info.java | 1 + mockwebserver/src/main/java9/module-info.java | 1 + module-tests/src/main/java/module-info.java | 1 + module-tests/src/test/java/module-info.java | 1 + okhttp-brotli/src/main/java9/module-info.java | 1 + okhttp-coroutines/src/main/java9/module-info.java | 1 + okhttp-dnsoverhttps/src/main/java9/module-info.java | 1 + okhttp-java-net-cookiejar/src/main/java9/module-info.java | 1 + okhttp-logging-interceptor/src/main/java9/module-info.java | 1 + okhttp-sse/src/main/java9/module-info.java | 1 + okhttp-tls/src/main/java9/module-info.java | 1 + okhttp-urlconnection/src/main/java9/module-info.java | 1 + okhttp/src/jvmMain/java9/module-info.java | 1 + 15 files changed, 15 insertions(+) diff --git a/mockwebserver-deprecated/src/main/java9/module-info.java b/mockwebserver-deprecated/src/main/java9/module-info.java index 4027da9a1f1e..5cbe5dcf8688 100644 --- a/mockwebserver-deprecated/src/main/java9/module-info.java +++ b/mockwebserver-deprecated/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.mockwebserver { requires okhttp3; exports okhttp3.mockwebserver; diff --git a/mockwebserver-junit4/src/main/java9/module-info.java b/mockwebserver-junit4/src/main/java9/module-info.java index 767bb5fa6a61..9b8df1850ed1 100644 --- a/mockwebserver-junit4/src/main/java9/module-info.java +++ b/mockwebserver-junit4/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module mockwebserver3.junit4 { requires okhttp3; exports mockwebserver3.junit4; diff --git a/mockwebserver-junit5/src/main/java9/module-info.java b/mockwebserver-junit5/src/main/java9/module-info.java index 9395144f6393..a17efe6c8e70 100644 --- a/mockwebserver-junit5/src/main/java9/module-info.java +++ b/mockwebserver-junit5/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module mockwebserver3.junit5 { requires okhttp3; opens mockwebserver3.junit5.internal; diff --git a/mockwebserver/src/main/java9/module-info.java b/mockwebserver/src/main/java9/module-info.java index 82bb585408b9..c0f61f230c2f 100644 --- a/mockwebserver/src/main/java9/module-info.java +++ b/mockwebserver/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module mockwebserver3 { requires okhttp3; exports mockwebserver3; diff --git a/module-tests/src/main/java/module-info.java b/module-tests/src/main/java/module-info.java index 0c9cd1356026..c4f26a544128 100644 --- a/module-tests/src/main/java/module-info.java +++ b/module-tests/src/main/java/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.modules { requires okhttp3; requires okhttp3.logging; diff --git a/module-tests/src/test/java/module-info.java b/module-tests/src/test/java/module-info.java index 67bdb8597b83..39c64ca3aa58 100644 --- a/module-tests/src/test/java/module-info.java +++ b/module-tests/src/test/java/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.modules.test { requires okhttp3; requires okhttp3.logging; diff --git a/okhttp-brotli/src/main/java9/module-info.java b/okhttp-brotli/src/main/java9/module-info.java index 3e1fd23895b1..488eb21d0843 100644 --- a/okhttp-brotli/src/main/java9/module-info.java +++ b/okhttp-brotli/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.brotli { requires okhttp3; exports okhttp3.brotli; diff --git a/okhttp-coroutines/src/main/java9/module-info.java b/okhttp-coroutines/src/main/java9/module-info.java index f9aa3b8a8855..13ec76f4b1e5 100644 --- a/okhttp-coroutines/src/main/java9/module-info.java +++ b/okhttp-coroutines/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.coroutines { requires okhttp3; exports okhttp3.coroutines; diff --git a/okhttp-dnsoverhttps/src/main/java9/module-info.java b/okhttp-dnsoverhttps/src/main/java9/module-info.java index 3bf55cbf82c2..51bac70ba42f 100644 --- a/okhttp-dnsoverhttps/src/main/java9/module-info.java +++ b/okhttp-dnsoverhttps/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.dnsoverhttps { requires okhttp3; exports okhttp3.dnsoverhttps; diff --git a/okhttp-java-net-cookiejar/src/main/java9/module-info.java b/okhttp-java-net-cookiejar/src/main/java9/module-info.java index 4370bdf653e9..eb204e7e4696 100644 --- a/okhttp-java-net-cookiejar/src/main/java9/module-info.java +++ b/okhttp-java-net-cookiejar/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.java.net.cookiejar { requires okhttp3; exports okhttp3.java.net.cookiejar; diff --git a/okhttp-logging-interceptor/src/main/java9/module-info.java b/okhttp-logging-interceptor/src/main/java9/module-info.java index f8c06849fca0..3bd226e16d89 100644 --- a/okhttp-logging-interceptor/src/main/java9/module-info.java +++ b/okhttp-logging-interceptor/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.logging { requires okhttp3; exports okhttp3.logging; diff --git a/okhttp-sse/src/main/java9/module-info.java b/okhttp-sse/src/main/java9/module-info.java index 8b99bdda31c6..1c9afaa9e84b 100644 --- a/okhttp-sse/src/main/java9/module-info.java +++ b/okhttp-sse/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.sse { requires okhttp3; exports okhttp3.sse; diff --git a/okhttp-tls/src/main/java9/module-info.java b/okhttp-tls/src/main/java9/module-info.java index 76f003d651a2..64ab58c72120 100644 --- a/okhttp-tls/src/main/java9/module-info.java +++ b/okhttp-tls/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.tls { requires okhttp3; exports okhttp3.tls; diff --git a/okhttp-urlconnection/src/main/java9/module-info.java b/okhttp-urlconnection/src/main/java9/module-info.java index db7ef95c8370..fb3501129fa6 100644 --- a/okhttp-urlconnection/src/main/java9/module-info.java +++ b/okhttp-urlconnection/src/main/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3.urlconnection { requires okhttp3; } diff --git a/okhttp/src/jvmMain/java9/module-info.java b/okhttp/src/jvmMain/java9/module-info.java index c215e128d09c..86d49af5e2d5 100644 --- a/okhttp/src/jvmMain/java9/module-info.java +++ b/okhttp/src/jvmMain/java9/module-info.java @@ -1,3 +1,4 @@ +@SuppressWarnings("module") module okhttp3 { requires transitive kotlin.stdlib; requires transitive okio; From 220529bbb1c7375ad2a14e4d7b995acc2ba7a33a Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 10:27:34 +0100 Subject: [PATCH 15/24] add --- module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java b/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java index beb81d1c5fc2..1239afe74a44 100644 --- a/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java +++ b/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java @@ -19,7 +19,7 @@ import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.Request; -//import okhttp3.logging.LoggingEventListener; +import okhttp3.logging.LoggingEventListener; /** * Just checking compilation works From c2bb349180eb8b38db373ca46373d9dc92ebf02e Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 10:32:19 +0100 Subject: [PATCH 16/24] add --- README.md | 11 +++++++++++ .../src/main/java/okhttp3/modules/OkHttpCaller.java | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 78628e566d3d..bfcc0feeb815 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,17 @@ Java Modules ------------ OkHttp (5.3+) implements Java 9 Modules such that in Java builds. + +With this in place Java builds should fail if apps attempt to use internal packages. + +``` +error: package okhttp3.internal.platform is not visible + okhttp3.internal.platform.Platform.get(); + ^ + (package okhttp3.internal.platform is declared in module okhttp3, + which does not export it to module i.am.bad.and.i.should.feel.bad) +``` + The list of defined modules is: - okhttp3 diff --git a/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java b/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java index 1239afe74a44..32817bd132d2 100644 --- a/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java +++ b/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java @@ -19,6 +19,7 @@ import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.Request; +import okhttp3.logging.HttpLoggingInterceptor; import okhttp3.logging.LoggingEventListener; /** @@ -28,7 +29,7 @@ public class OkHttpCaller { public static Call callOkHttp() { OkHttpClient client = new OkHttpClient .Builder() - .eventListenerFactory(LoggingEventListener.Factory()) + .eventListenerFactory(new LoggingEventListener.Factory(HttpLoggingInterceptor.Logger.DEFAULT)) .build(); return client.newCall(new Request.Builder().url("https://square.com/robots.txt").build()); } From 1488a1b5bf3677bf119cf82de25f1c91ba85e9b4 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 10:35:02 +0100 Subject: [PATCH 17/24] readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bfcc0feeb815..85ae2001d266 100644 --- a/README.md +++ b/README.md @@ -216,7 +216,7 @@ $ ./okcurl/build/graal/okcurl https://httpbin.org/get Java Modules ------------ -OkHttp (5.3+) implements Java 9 Modules such that in Java builds. +OkHttp (5.3+) implements Java 9 Modules. With this in place Java builds should fail if apps attempt to use internal packages. @@ -228,7 +228,7 @@ error: package okhttp3.internal.platform is not visible which does not export it to module i.am.bad.and.i.should.feel.bad) ``` -The list of defined modules is: +The stable public API is based on the list of defined modules: - okhttp3 - okhttp3.brotli From b028111a0a50bce60eda1db5f8e9cc09656b6664 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 10:44:41 +0100 Subject: [PATCH 18/24] add more modules --- okhttp/src/jvmMain/java9/module-info.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/okhttp/src/jvmMain/java9/module-info.java b/okhttp/src/jvmMain/java9/module-info.java index 86d49af5e2d5..a9f4dbe0a84d 100644 --- a/okhttp/src/jvmMain/java9/module-info.java +++ b/okhttp/src/jvmMain/java9/module-info.java @@ -2,7 +2,11 @@ module okhttp3 { requires transitive kotlin.stdlib; requires transitive okio; + requires java.io; requires java.logging; + requires java.net; + requires java.util; + requires javax.net.ssl; exports okhttp3; exports okhttp3.internal to okhttp3.logging, okhttp3.sse, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.coroutines, okhttp3.tls; exports okhttp3.internal.platform to okhttp3.logging, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.tls; From fb8636d5f08ed8cb3d155f4d998683fae2589be5 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 10:51:58 +0100 Subject: [PATCH 19/24] Fix --- okhttp/src/jvmMain/java9/module-info.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/okhttp/src/jvmMain/java9/module-info.java b/okhttp/src/jvmMain/java9/module-info.java index a9f4dbe0a84d..86d49af5e2d5 100644 --- a/okhttp/src/jvmMain/java9/module-info.java +++ b/okhttp/src/jvmMain/java9/module-info.java @@ -2,11 +2,7 @@ module okhttp3 { requires transitive kotlin.stdlib; requires transitive okio; - requires java.io; requires java.logging; - requires java.net; - requires java.util; - requires javax.net.ssl; exports okhttp3; exports okhttp3.internal to okhttp3.logging, okhttp3.sse, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.coroutines, okhttp3.tls; exports okhttp3.internal.platform to okhttp3.logging, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.tls; From 45ec46b4b9577a31e6890f3f3e6647c9e76ac0e2 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 11:00:54 +0100 Subject: [PATCH 20/24] Run with Jlink --- .github/workflows/build.yml | 20 ++++++++++++++++++++ module-tests/build.gradle.kts | 13 ++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad6e41d8d922..71c5abcfd923 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -692,3 +692,23 @@ jobs: - name: Run maven test working-directory: ./maven-tests run: ./mvnw -q verify + + test_java_modules: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure JDK + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: 24 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Run with Jlink + run: ./gradlew module-tests:imageRun + diff --git a/module-tests/build.gradle.kts b/module-tests/build.gradle.kts index a54f2906e20a..0cac5f3210ca 100644 --- a/module-tests/build.gradle.kts +++ b/module-tests/build.gradle.kts @@ -1,11 +1,9 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - plugins { id("java") id("application") id("com.github.iherasymenko.jlink") version "0.7" - id("org.gradlex.extra-java-module-info") version "1.12" + id("org.gradlex.extra-java-module-info") version "1.13" + id("com.ryandens.jlink-application") version "0.4.1" } dependencies { @@ -22,7 +20,7 @@ dependencies { application { mainClass = "okhttp3.modules.Main" - mainModule = "okhttp3.module.tests" + mainModule = "okhttp3.modules" } extraJavaModuleInfo { @@ -58,3 +56,8 @@ java { languageVersion.set(JavaLanguageVersion.of(21)) } } + +jlinkJre { + modules.addAll("jdk.crypto.ec", "java.logging") + stripDebug.set(true) +} From d9d121f36bc7c95ee0c3e21e54e3dd0400fb0681 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 11:28:13 +0100 Subject: [PATCH 21/24] Add mockwebserver test --- module-tests/build.gradle.kts | 2 ++ .../src/main/java/okhttp3/modules/Main.java | 3 ++- .../java/okhttp3/modules/OkHttpCaller.java | 5 ++-- module-tests/src/test/java/module-info.java | 2 ++ .../okhttp3/modules/test/JavaModuleTest.java | 24 ++++++++++++++++++- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/module-tests/build.gradle.kts b/module-tests/build.gradle.kts index 0cac5f3210ca..d73c22120230 100644 --- a/module-tests/build.gradle.kts +++ b/module-tests/build.gradle.kts @@ -12,6 +12,8 @@ dependencies { testImplementation(projects.okhttp) testImplementation(projects.loggingInterceptor) + testImplementation(projects.mockwebserver3) + testImplementation(projects.mockwebserver3Junit5) testImplementation(libs.junit.jupiter.api) testRuntimeOnly(libs.junit.jupiter.engine) diff --git a/module-tests/src/main/java/okhttp3/modules/Main.java b/module-tests/src/main/java/okhttp3/modules/Main.java index 9900a9a45f0a..0467303f4716 100644 --- a/module-tests/src/main/java/okhttp3/modules/Main.java +++ b/module-tests/src/main/java/okhttp3/modules/Main.java @@ -17,12 +17,13 @@ package okhttp3.modules; import okhttp3.Call; +import okhttp3.HttpUrl; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { - Call call = OkHttpCaller.callOkHttp(); + Call call = OkHttpCaller.callOkHttp(HttpUrl.get("https://square.com/robots.txt")); System.out.println(call.execute().body().string()); } diff --git a/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java b/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java index 32817bd132d2..a5e11395eaec 100644 --- a/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java +++ b/module-tests/src/main/java/okhttp3/modules/OkHttpCaller.java @@ -17,6 +17,7 @@ package okhttp3.modules; import okhttp3.Call; +import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.logging.HttpLoggingInterceptor; @@ -26,11 +27,11 @@ * Just checking compilation works */ public class OkHttpCaller { - public static Call callOkHttp() { + public static Call callOkHttp(HttpUrl url) { OkHttpClient client = new OkHttpClient .Builder() .eventListenerFactory(new LoggingEventListener.Factory(HttpLoggingInterceptor.Logger.DEFAULT)) .build(); - return client.newCall(new Request.Builder().url("https://square.com/robots.txt").build()); + return client.newCall(new Request.Builder().url(url).build()); } } diff --git a/module-tests/src/test/java/module-info.java b/module-tests/src/test/java/module-info.java index 39c64ca3aa58..492bc17656f3 100644 --- a/module-tests/src/test/java/module-info.java +++ b/module-tests/src/test/java/module-info.java @@ -2,6 +2,8 @@ module okhttp3.modules.test { requires okhttp3; requires okhttp3.logging; + requires mockwebserver3; + requires mockwebserver3.junit5; requires jdk.crypto.ec; requires org.junit.jupiter.api; requires okhttp3.modules; diff --git a/module-tests/src/test/java/okhttp3/modules/test/JavaModuleTest.java b/module-tests/src/test/java/okhttp3/modules/test/JavaModuleTest.java index c81944502c8e..a6c5e91eb4bf 100644 --- a/module-tests/src/test/java/okhttp3/modules/test/JavaModuleTest.java +++ b/module-tests/src/test/java/okhttp3/modules/test/JavaModuleTest.java @@ -16,11 +16,19 @@ package okhttp3.modules.test; +import mockwebserver3.MockResponse; +import mockwebserver3.MockWebServer; +import okhttp3.Call; +import okhttp3.Headers; +import okhttp3.HttpUrl; import okhttp3.OkHttpClient; +import okhttp3.Response; import okhttp3.logging.HttpLoggingInterceptor; import okhttp3.modules.OkHttpCaller; import org.junit.jupiter.api.Test; +import java.io.IOException; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -28,7 +36,21 @@ class JavaModuleTest { @Test public void testVisibility() { // Just check we can run code that depends on OkHttp types - OkHttpCaller.callOkHttp(); + OkHttpCaller.callOkHttp(HttpUrl.get("https://square.com/robots.txt")); + } + + @Test + public void testMockWebServer() throws IOException { + MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse(200, Headers.of(), "Hello, Java9!")); + server.start(); + + // Just check we can run code that depends on OkHttp types + Call call = OkHttpCaller.callOkHttp(server.url("/")); + + try (Response response = call.execute();) { + System.out.println(response.body().string()); + } } @Test From 2398c5acc6a3a062e99718f8b2c11fec3c1d2d7d Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 11:45:33 +0100 Subject: [PATCH 22/24] Fix build --- module-tests/build.gradle.kts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/module-tests/build.gradle.kts b/module-tests/build.gradle.kts index d73c22120230..55b1eb629ac8 100644 --- a/module-tests/build.gradle.kts +++ b/module-tests/build.gradle.kts @@ -3,7 +3,6 @@ plugins { id("application") id("com.github.iherasymenko.jlink") version "0.7" id("org.gradlex.extra-java-module-info") version "1.13" - id("com.ryandens.jlink-application") version "0.4.1" } dependencies { @@ -25,6 +24,11 @@ application { mainModule = "okhttp3.modules" } +jlinkApplication { + stripDebug = true + addModules.addAll("jdk.crypto.ec", "java.logging") +} + extraJavaModuleInfo { module("org.jetbrains:annotations", "org.jetbrains.annotations") { exportAllPackages() @@ -58,8 +62,3 @@ java { languageVersion.set(JavaLanguageVersion.of(21)) } } - -jlinkJre { - modules.addAll("jdk.crypto.ec", "java.logging") - stripDebug.set(true) -} From c6bf693262f659901d3d404e4dcf42d4fa1bbb06 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 19 Jul 2025 11:49:36 +0100 Subject: [PATCH 23/24] Fix build --- module-tests/build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/module-tests/build.gradle.kts b/module-tests/build.gradle.kts index 55b1eb629ac8..570e38dbcd95 100644 --- a/module-tests/build.gradle.kts +++ b/module-tests/build.gradle.kts @@ -26,7 +26,10 @@ application { jlinkApplication { stripDebug = true + stripJavaDebugAttributes = true + compress.set("zip-9") addModules.addAll("jdk.crypto.ec", "java.logging") + vm.set("server") } extraJavaModuleInfo { From cb0deddbf4b35271a8b5f15ececbad636e2ea36d Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sat, 16 Aug 2025 09:30:32 +0100 Subject: [PATCH 24/24] Fix build --- okhttp/src/jvmMain/java9/module-info.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/okhttp/src/jvmMain/java9/module-info.java b/okhttp/src/jvmMain/java9/module-info.java index 86d49af5e2d5..7ff3c9e58c44 100644 --- a/okhttp/src/jvmMain/java9/module-info.java +++ b/okhttp/src/jvmMain/java9/module-info.java @@ -5,10 +5,11 @@ requires java.logging; exports okhttp3; exports okhttp3.internal to okhttp3.logging, okhttp3.sse, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.coroutines, okhttp3.tls; - exports okhttp3.internal.platform to okhttp3.logging, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.tls; + exports okhttp3.internal.concurrent to mockwebserver3, okhttp3.mockwebserver; + exports okhttp3.internal.connection to mockwebserver3, okhttp3.mockwebserver; exports okhttp3.internal.http to okhttp3.logging, okhttp3.brotli, mockwebserver3; exports okhttp3.internal.http2 to mockwebserver3, okhttp3.mockwebserver; - exports okhttp3.internal.concurrent to mockwebserver3, okhttp3.mockwebserver; - exports okhttp3.internal.ws to mockwebserver3, okhttp3.mockwebserver; + exports okhttp3.internal.platform to okhttp3.logging, okhttp3.java.net.cookiejar, okhttp3.dnsoverhttps, mockwebserver3, okhttp3.mockwebserver, okhttp3.tls; exports okhttp3.internal.publicsuffix to okhttp3.dnsoverhttps; + exports okhttp3.internal.ws to mockwebserver3, okhttp3.mockwebserver; }