From e3aabfdd7e4084edc5163f4ead07b253ba87a175 Mon Sep 17 00:00:00 2001 From: "loushaokun.3" Date: Tue, 4 Aug 2026 16:33:14 +0800 Subject: [PATCH] Support Kotlin Multiplatform in applyJavaModules --- build-logic/src/main/kotlin/JavaModules.kt | 108 ++++++++++++++++++--- okhttp/build.gradle.kts | 80 +-------------- 2 files changed, 97 insertions(+), 91 deletions(-) diff --git a/build-logic/src/main/kotlin/JavaModules.kt b/build-logic/src/main/kotlin/JavaModules.kt index e650a0b09fc7..8598f7483704 100644 --- a/build-logic/src/main/kotlin/JavaModules.kt +++ b/build-logic/src/main/kotlin/JavaModules.kt @@ -15,13 +15,17 @@ */ import me.champeau.mrjar.MultiReleaseExtension +import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.jvm.toolchain.JavaToolchainService import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.getByType import org.gradle.kotlin.dsl.named +import org.gradle.kotlin.dsl.register import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile fun Project.applyJavaModules( @@ -29,6 +33,30 @@ fun Project.applyJavaModules( defaultVersion: Int = 8, javaModuleVersion: Int = 9, enableValidation: Boolean = true, +) { + plugins.withId("org.jetbrains.kotlin.jvm") { + applyJavaModulesJvm( + moduleName = moduleName, + defaultVersion = defaultVersion, + javaModuleVersion = javaModuleVersion, + enableValidation = enableValidation, + ) + } + + plugins.withId("org.jetbrains.kotlin.multiplatform") { + applyJavaModulesMultiplatform( + moduleName = moduleName, + javaModuleVersion = javaModuleVersion, + enableValidation = enableValidation, + ) + } +} + +private fun Project.applyJavaModulesJvm( + moduleName: String, + defaultVersion: Int, + javaModuleVersion: Int, + enableValidation: Boolean, ) { plugins.apply("me.champeau.mrjar") @@ -38,29 +66,79 @@ fun Project.applyJavaModules( tasks.named("compileJava9Java").configure { val compileKotlinTask = tasks.getByName("compileKotlin") as KotlinJvmCompile - dependsOn(compileKotlinTask) if (enableValidation) { 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. - options.compilerArgs.addAll( - listOf( - "--patch-module", - "$moduleName=${compileKotlinTask.destinationDirectory.get().asFile}", - ), - ) - - classpath = compileKotlinTask.libraries - modularity.inferModulePath.set(true) + configureModuleInfoCompilation(moduleName, compileKotlinTask) val javaToolchains = project.extensions.getByType() val javaPluginExtension = project.extensions.getByType() javaCompiler.set(javaToolchains.compilerFor(javaPluginExtension.toolchain)) } } + +private fun Project.applyJavaModulesMultiplatform( + moduleName: String, + javaModuleVersion: Int, + enableValidation: Boolean, +) { + val compileJavaModuleInfo = + tasks.register("compileJavaModuleInfo") { + val compileKotlinTask = tasks.getByName("compileKotlinJvm") as KotlinJvmCompile + val targetDir = compileKotlinTask.destinationDirectory.dir("../java9") + val sourceDir = file("src/jvmMain/java9") + + val javaToolchains = project.extensions.getByType() + javaCompiler.set( + javaToolchains.compilerFor { + languageVersion.set(JavaLanguageVersion.of(11)) + }, + ) + + source(sourceDir) + if (enableValidation) { + compileKotlinTask.source(sourceDir) + } + + outputs.dir(targetDir) + destinationDirectory.set(targetDir) + sourceCompatibility = JavaVersion.toVersion(javaModuleVersion).toString() + targetCompatibility = JavaVersion.toVersion(javaModuleVersion).toString() + options.release.set(javaModuleVersion) + + configureModuleInfoCompilation(moduleName, compileKotlinTask) + } + + tasks.named("jvmJar").configure { + manifest { + attributes(mapOf("Multi-Release" to true)) + } + + from(compileJavaModuleInfo.map { it.destinationDirectory }) { + into("META-INF/versions/9/") + } + } +} + +private fun JavaCompile.configureModuleInfoCompilation( + moduleName: String, + compileKotlinTask: KotlinJvmCompile, +) { + dependsOn(compileKotlinTask) + + // Ignore warnings about using 'requires transitive' on automatic modules. + options.compilerArgs.add("-Xlint:-requires-transitive-automatic") + + // Patch the Kotlin output 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/okhttp/build.gradle.kts b/okhttp/build.gradle.kts index 54e5fc443a39..88dd16c3bbb3 100644 --- a/okhttp/build.gradle.kts +++ b/okhttp/build.gradle.kts @@ -4,7 +4,6 @@ import okhttp3.buildsupport.alpnBootVersion import okhttp3.buildsupport.platform import okhttp3.buildsupport.testJavaVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile import ru.vyarus.gradle.plugin.animalsniffer.AnimalSniffer import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension @@ -216,81 +215,10 @@ if (platform == "jdk8alpn") { } } -// 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) -} - -// Call the convention when the task has finished, to modify the jar to contain OSGi metadata. -tasks.named("jvmJar").configure { - manifest { - attributes( - "Multi-Release" to true, - ) - } - - from(compileJavaModuleInfo.map { it.destinationDirectory }) { - into("META-INF/versions/9/") - } -} +project.applyJavaModules( + moduleName = "okhttp3", + enableValidation = false, +) project.applyOsgiMultiplatform( "Export-Package: okhttp3,okhttp3.internal.*;okhttpinternal=true;mandatory:=okhttpinternal",