Skip to content

Commit 5b2a1e1

Browse files
authored
Split okhttp core into Android and JVM (square#8600)
1 parent 6947be1 commit 5b2a1e1

File tree

322 files changed

+1824
-311
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

322 files changed

+1824
-311
lines changed

android-test-app/src/main/kotlin/okhttp/android/testapp/MainActivity.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
2323
import okhttp3.OkHttpClient
2424
import okhttp3.Request
2525
import okhttp3.Response
26+
import okhttp3.internal.platform.AndroidPlatform
2627
import okio.IOException
2728

2829
class MainActivity : ComponentActivity() {
@@ -31,6 +32,9 @@ class MainActivity : ComponentActivity() {
3132

3233
val client = OkHttpClient()
3334

35+
// Ensure we are compiling against the right variant
36+
println(AndroidPlatform.isSupported)
37+
3438
val url = "https://github.com/square/okhttp".toHttpUrl()
3539
println(url.topPrivateDomain())
3640

build.gradle.kts

Lines changed: 76 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat
88
import org.jetbrains.dokka.gradle.DokkaTaskPartial
99
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
1010
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
11+
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
1112
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
1213
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension
1314
import java.net.URI
@@ -93,11 +94,16 @@ subprojects {
9394

9495
apply(plugin = "checkstyle")
9596
apply(plugin = "ru.vyarus.animalsniffer")
96-
apply(plugin = "biz.aQute.bnd.builder")
97-
apply(plugin = "io.github.usefulness.maven-sympathy")
97+
98+
// The 'java' plugin has been applied, but it is not compatible with the Android plugins.
99+
// These are applied inside the okhttp module for that case specifically
100+
if (project.name != "okhttp") {
101+
apply(plugin = "biz.aQute.bnd.builder")
102+
apply(plugin = "io.github.usefulness.maven-sympathy")
103+
}
98104

99105
// Skip samples parent
100-
if (project.buildFile.exists()) {
106+
if (project.buildFile.exists() && project.name != "okhttp") {
101107
apply(plugin = "com.android.lint")
102108

103109
dependencies {
@@ -109,9 +115,11 @@ subprojects {
109115
options.encoding = Charsets.UTF_8.toString()
110116
}
111117

112-
configure<JavaPluginExtension> {
113-
toolchain {
114-
languageVersion.set(JavaLanguageVersion.of(17))
118+
if (plugins.hasPlugin(JavaBasePlugin::class.java)) {
119+
extensions.configure<JavaPluginExtension> {
120+
toolchain {
121+
languageVersion.set(JavaLanguageVersion.of(17))
122+
}
115123
}
116124
}
117125

@@ -126,33 +134,38 @@ subprojects {
126134
}
127135
}
128136

129-
configure<CheckstyleExtension> {
130-
config = resources.text.fromArchiveEntry(checkstyleConfig, "google_checks.xml")
131-
toolVersion = rootProject.libs.versions.checkStyle.get()
132-
sourceSets = listOf(project.sourceSets["main"])
133-
}
137+
// Handled in :okhttp directly
138+
if (project.name != "okhttp") {
139+
configure<CheckstyleExtension> {
140+
config = resources.text.fromArchiveEntry(checkstyleConfig, "google_checks.xml")
141+
toolVersion = rootProject.libs.versions.checkStyle.get()
142+
sourceSets = listOf(project.sourceSets["main"])
143+
}
134144

135-
// Animal Sniffer confirms we generally don't use APIs not on Java 8.
136-
configure<AnimalSnifferExtension> {
137-
annotation = "okhttp3.internal.SuppressSignatureCheck"
138-
sourceSets = listOf(project.sourceSets["main"])
145+
// Animal Sniffer confirms we generally don't use APIs not on Java 8.
146+
configure<AnimalSnifferExtension> {
147+
annotation = "okhttp3.internal.SuppressSignatureCheck"
148+
sourceSets = listOf(project.sourceSets["main"])
149+
}
139150
}
140151

141-
val signature: Configuration by configurations.getting
142152
dependencies {
143153
// No dependency requirements for testing-support.
144154
if (project.name == "okhttp-testing-support") return@dependencies
145155

156+
// okhttp configured specifically.
157+
if (project.name == "okhttp") return@dependencies
158+
146159
if (project.name == "mockwebserver3-junit5") {
147160
// JUnit 5's APIs need java.util.function.Function and java.util.Optional from API 24.
148-
signature(rootProject.libs.signature.android.apilevel24) { artifact { type = "signature" } }
161+
"signature"(rootProject.libs.signature.android.apilevel24) { artifact { type = "signature" } }
149162
} else {
150163
// Everything else requires Android API 21+.
151-
signature(rootProject.libs.signature.android.apilevel21) { artifact { type = "signature" } }
164+
"signature"(rootProject.libs.signature.android.apilevel21) { artifact { type = "signature" } }
152165
}
153166

154167
// OkHttp requires Java 8+.
155-
signature(rootProject.libs.codehaus.signature.java18) { artifact { type = "signature" } }
168+
"signature"(rootProject.libs.codehaus.signature.java18) { artifact { type = "signature" } }
156169
}
157170

158171
val javaVersionSetting =
@@ -175,10 +188,15 @@ subprojects {
175188
}
176189
}
177190

178-
val testRuntimeOnly: Configuration by configurations.getting
179-
dependencies {
180-
testRuntimeOnly(rootProject.libs.junit.jupiter.engine)
181-
testRuntimeOnly(rootProject.libs.junit.vintage.engine)
191+
val platform = System.getProperty("okhttp.platform", "jdk9")
192+
val testJavaVersion = System.getProperty("test.java.version", "21").toInt()
193+
194+
if (project.name != "okhttp") {
195+
val testRuntimeOnly: Configuration by configurations.getting
196+
dependencies {
197+
testRuntimeOnly(rootProject.libs.junit.jupiter.engine)
198+
testRuntimeOnly(rootProject.libs.junit.vintage.engine)
199+
}
182200
}
183201

184202
tasks.withType<Test> {
@@ -211,25 +229,30 @@ subprojects {
211229
tasks.withType<Test>().configureEach {
212230
environment("OKHTTP_ROOT", rootDir)
213231
}
232+
tasks.withType<KotlinJvmTest>().configureEach {
233+
environment("OKHTTP_ROOT", rootDir)
234+
}
214235

215-
if (platform == "jdk8alpn") {
216-
// Add alpn-boot on Java 8 so we can use HTTP/2 without a stable API.
217-
val alpnBootVersion = alpnBootVersion()
218-
if (alpnBootVersion != null) {
219-
val alpnBootJar = configurations.detachedConfiguration(
220-
dependencies.create("org.mortbay.jetty.alpn:alpn-boot:$alpnBootVersion")
221-
).singleFile
222-
tasks.withType<Test> {
223-
jvmArgs("-Xbootclasspath/p:${alpnBootJar}")
236+
if (project.name != "okhttp") {
237+
if (platform == "jdk8alpn") {
238+
// Add alpn-boot on Java 8 so we can use HTTP/2 without a stable API.
239+
val alpnBootVersion = alpnBootVersion()
240+
if (alpnBootVersion != null) {
241+
val alpnBootJar = configurations.detachedConfiguration(
242+
dependencies.create("org.mortbay.jetty.alpn:alpn-boot:$alpnBootVersion")
243+
).singleFile
244+
tasks.withType<Test> {
245+
jvmArgs("-Xbootclasspath/p:${alpnBootJar}")
246+
}
247+
}
248+
} else if (platform == "conscrypt") {
249+
dependencies {
250+
// testRuntimeOnly(rootProject.libs.conscrypt.openjdk)
251+
}
252+
} else if (platform == "openjsse") {
253+
dependencies {
254+
// testRuntimeOnly(rootProject.libs.openjsse)
224255
}
225-
}
226-
} else if (platform == "conscrypt") {
227-
dependencies {
228-
testRuntimeOnly(rootProject.libs.conscrypt.openjdk)
229-
}
230-
} else if (platform == "openjsse") {
231-
dependencies {
232-
testRuntimeOnly(rootProject.libs.openjsse)
233256
}
234257
}
235258

@@ -246,6 +269,11 @@ subprojects {
246269
languageSettings.optIn("okhttp3.ExperimentalOkHttpApi")
247270
}
248271
}
272+
plugins.withId("org.jetbrains.kotlin.multiplatform") {
273+
kotlinExtension.sourceSets.configureEach {
274+
languageSettings.optIn("okhttp3.ExperimentalOkHttpApi")
275+
}
276+
}
249277
plugins.withId("org.jetbrains.kotlin.android") {
250278
kotlinExtension.sourceSets.configureEach {
251279
languageSettings.optIn("okhttp3.ExperimentalOkHttpApi")
@@ -316,6 +344,14 @@ subprojects {
316344
}
317345
}
318346

347+
plugins.withId("org.jetbrains.kotlin.jvm") {
348+
val test = tasks.named("test")
349+
tasks.register("jvmTest") {
350+
description = "Get 'gradlew jvmTest' to run the tests of JVM-only modules"
351+
dependsOn(test)
352+
}
353+
}
354+
319355
tasks.wrapper {
320356
distributionType = Wrapper.DistributionType.ALL
321357
}

buildSrc/settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rootProject.name = "okhttp-buildSrc"

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ org.gradle.caching=true
22
org.gradle.parallel=true
33

44
android.useAndroidX=true
5+
kotlin.mpp.applyDefaultHierarchyTemplate=false
56

67
androidBuild=false
78
graalBuild=false

gradle/libs.versions.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ gradlePlugin-androidJunit5 = "de.mannodermaus.gradle.plugins:android-junit5:1.11
4747
gradlePlugin-animalsniffer = "ru.vyarus:gradle-animalsniffer-plugin:1.7.2"
4848
gradlePlugin-binaryCompatibilityValidator = "org.jetbrains.kotlinx.binary-compatibility-validator:org.jetbrains.kotlinx.binary-compatibility-validator.gradle.plugin:0.17.0"
4949
gradlePlugin-bnd = { module = "biz.aQute.bnd:biz.aQute.bnd.gradle", version.ref = "biz-aQute-bnd" }
50-
gradlePlugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:1.9.20"
50+
gradlePlugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:2.0.0"
5151
gradlePlugin-errorprone = "net.ltgt.gradle:gradle-errorprone-plugin:4.1.0"
5252
gradlePlugin-graalvmBuildTools = "org.graalvm.buildtools.native:org.graalvm.buildtools.native.gradle.plugin:0.10.4"
5353
gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "org-jetbrains-kotlin" }
@@ -78,7 +78,6 @@ kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "
7878
kotlin-stdlib-osgi = { module = "org.jetbrains.kotlin:kotlin-osgi-bundle", version.ref = "org-jetbrains-kotlin" }
7979
kotlin-test-annotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "org-jetbrains-kotlin" }
8080
kotlin-test-common = { module = "org.jetbrains.kotlin:kotlin-test-common", version.ref = "org-jetbrains-kotlin" }
81-
kotlin-test-js = { module = "org.jetbrains.kotlin:kotlin-test-js", version.ref = "org-jetbrains-kotlin" }
8281
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "org-jetbrains-kotlin" }
8382
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "org-jetbrains-coroutines" }
8483
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "org-jetbrains-coroutines" }

mockwebserver-junit4/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ dependencies {
1919
api(libs.junit)
2020

2121
testImplementation(libs.assertk)
22+
testImplementation(libs.junit.vintage.engine)
2223
}
2324

2425
mavenPublishing {

okcurl/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ tasks.shadowJar {
5555
mergeServiceFiles()
5656
}
5757

58-
5958
if (testJavaVersion >= 11) {
6059
apply(plugin = "org.graalvm.buildtools.native")
6160

okhttp-android/build.gradle.kts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,19 @@ dependencies {
6464
testImplementation(libs.robolectric)
6565
testImplementation(libs.androidx.espresso.core)
6666
testImplementation(libs.squareup.okio.fakefilesystem)
67+
testImplementation(projects.okhttpTestingSupport)
68+
testImplementation(rootProject.libs.conscrypt.openjdk)
6769

6870
androidTestImplementation(projects.okhttpTls)
6971
androidTestImplementation(libs.assertk)
7072
androidTestImplementation(projects.mockwebserver3Junit4)
7173
androidTestImplementation(libs.androidx.test.runner)
7274
}
7375

74-
mavenPublishing {
75-
// AGP 7.2 embeds Dokka 4, which breaks publishing. Android modules are hardcoded to generate Javadoc instead of Gfm.
76-
configure(com.vanniktech.maven.publish.AndroidSingleVariantLibrary(publishJavadocJar=false))
77-
}
76+
// TODO remove this whole module after merging with okhttp
77+
// Conflicts with KMP :okhttp outputs
78+
79+
//mavenPublishing {
80+
// // AGP 7.2 embeds Dokka 4, which breaks publishing. Android modules are hardcoded to generate Javadoc instead of Gfm.
81+
// configure(com.vanniktech.maven.publish.AndroidSingleVariantLibrary(publishJavadocJar=false))
82+
//}

okhttp/src/test/java/okhttp3/internal/platform/android/AndroidSocketAdapterTest.kt renamed to okhttp-android/src/test/kotlin/okhttp3/android/AndroidSocketAdapterTest.kt

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package okhttp3.internal.platform.android
16+
package okhttp3.android
1717

1818
import java.security.Provider
1919
import javax.net.ssl.SSLContext
@@ -22,28 +22,25 @@ import okhttp3.DelegatingSSLSocket
2222
import okhttp3.DelegatingSSLSocketFactory
2323
import okhttp3.Protocol.HTTP_1_1
2424
import okhttp3.Protocol.HTTP_2
25-
import okhttp3.testing.PlatformRule
25+
import okhttp3.internal.platform.android.AndroidSocketAdapter
26+
import okhttp3.internal.platform.android.ConscryptSocketAdapter
27+
import okhttp3.internal.platform.android.DeferredSocketAdapter
28+
import okhttp3.internal.platform.android.SocketAdapter
29+
import okhttp3.internal.platform.android.StandardAndroidSocketAdapter
2630
import org.conscrypt.Conscrypt
2731
import org.junit.Assert.assertFalse
2832
import org.junit.Assert.assertNotNull
2933
import org.junit.Assert.assertNull
3034
import org.junit.Assert.assertTrue
3135
import org.junit.Assume.assumeFalse
3236
import org.junit.Assume.assumeTrue
33-
import org.junit.jupiter.api.BeforeEach
34-
import org.junit.jupiter.api.extension.RegisterExtension
35-
import org.junit.jupiter.params.ParameterizedTest
36-
import org.junit.jupiter.params.provider.MethodSource
37-
38-
class AndroidSocketAdapterTest {
39-
@RegisterExtension @JvmField
40-
val platform = PlatformRule()
41-
42-
@BeforeEach
43-
fun setUp() {
44-
platform.assumeConscrypt()
45-
}
37+
import org.junit.Test
38+
import org.junit.runner.RunWith
39+
import org.robolectric.ParameterizedRobolectricTestRunner
40+
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters
4641

42+
@RunWith(ParameterizedRobolectricTestRunner::class)
43+
class AndroidSocketAdapterTest(val adapter: SocketAdapter) {
4744
val context: SSLContext by lazy {
4845
val provider: Provider = Conscrypt.newProviderBuilder().provideTrustManager(true).build()
4946

@@ -52,9 +49,8 @@ class AndroidSocketAdapterTest {
5249
}
5350
}
5451

55-
@ParameterizedTest
56-
@MethodSource("data")
57-
fun testMatchesSupportedSocket(adapter: SocketAdapter) {
52+
@Test
53+
fun testMatchesSupportedSocket() {
5854
val socketFactory = context.socketFactory
5955

6056
val sslSocket = socketFactory.createSocket() as SSLSocket
@@ -65,27 +61,24 @@ class AndroidSocketAdapterTest {
6561
assertNull(adapter.getSelectedProtocol(sslSocket))
6662
}
6763

68-
@ParameterizedTest
69-
@MethodSource("data")
70-
fun testMatchesSupportedAndroidSocketFactory(adapter: SocketAdapter) {
64+
@Test
65+
fun testMatchesSupportedAndroidSocketFactory() {
7166
assumeTrue(adapter is StandardAndroidSocketAdapter)
7267

7368
assertTrue(adapter.matchesSocketFactory(context.socketFactory))
7469
assertNotNull(adapter.trustManager(context.socketFactory))
7570
}
7671

77-
@ParameterizedTest
78-
@MethodSource("data")
79-
fun testDoesntMatchSupportedCustomSocketFactory(adapter: SocketAdapter) {
72+
@Test
73+
fun testDoesntMatchSupportedCustomSocketFactory() {
8074
assumeFalse(adapter is StandardAndroidSocketAdapter)
8175

8276
assertFalse(adapter.matchesSocketFactory(context.socketFactory))
8377
assertNull(adapter.trustManager(context.socketFactory))
8478
}
8579

86-
@ParameterizedTest
87-
@MethodSource("data")
88-
fun testCustomSocket(adapter: SocketAdapter) {
80+
@Test
81+
fun testCustomSocket() {
8982
val socketFactory = DelegatingSSLSocketFactory(context.socketFactory)
9083

9184
assertFalse(adapter.matchesSocketFactory(socketFactory))
@@ -101,6 +94,7 @@ class AndroidSocketAdapterTest {
10194

10295
companion object {
10396
@JvmStatic
97+
@Parameters(name = "{0}")
10498
fun data(): Collection<SocketAdapter> {
10599
return listOfNotNull(
106100
DeferredSocketAdapter(ConscryptSocketAdapter.factory),

okhttp-android/src/test/kotlin/okhttp3/android/RobolectricOkHttpClientTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import org.robolectric.annotation.Config
4040

4141
@RunWith(RobolectricTestRunner::class)
4242
@Config(
43-
sdk = [30],
43+
sdk = [21, 26, 30, 33, 35],
4444
)
4545
class RobolectricOkHttpClientTest {
4646
private lateinit var context: Context

0 commit comments

Comments
 (0)