Skip to content

Commit e6401c6

Browse files
authored
Add explicit module-info for JPMS compatibility (#135)
1 parent acfd891 commit e6401c6

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

core/build.gradle.kts

+64-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import kotlinx.team.infra.mavenPublicationsPom
2+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
23
import java.net.URL
34
import java.util.Locale
45
import javax.xml.parsers.DocumentBuilderFactory
@@ -172,7 +173,7 @@ kotlin {
172173
dependencies {
173174
api("org.jetbrains.kotlin:kotlin-stdlib-js")
174175
api("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVersion")
175-
implementation(npm("@js-joda/core", "3.2.0"))
176+
implementation(npm("@js-joda/core", "3.2.0"))
176177
}
177178
}
178179

@@ -205,6 +206,68 @@ tasks {
205206
named("jvmTest", Test::class) {
206207
// maxHeapSize = "1024m"
207208
}
209+
210+
create("compileJavaModuleInfo", JavaCompile::class) {
211+
val moduleName = "kotlinx.datetime" // this module's name
212+
val compileKotlinJvm = getByName<KotlinCompile>("compileKotlinJvm")
213+
val sourceDir = file("jvm/java9/")
214+
val targetDir = compileKotlinJvm.destinationDir.resolve("../java9/")
215+
216+
// Use a Java 11 compiler for the module info.
217+
javaCompiler.set(project.javaToolchains.compilerFor { languageVersion.set(JavaLanguageVersion.of(11)) })
218+
219+
// Always compile kotlin classes before the module descriptor.
220+
dependsOn(compileKotlinJvm)
221+
222+
// Add the module-info source file.
223+
source(sourceDir)
224+
225+
// Also add the module-info.java source file to the Kotlin compile task.
226+
// The Kotlin compiler will parse and check module dependencies,
227+
// but it currently won't compile to a module-info.class file.
228+
// Note that module checking only works on JDK 9+,
229+
// because the JDK built-in base modules are not available in earlier versions.
230+
val javaVersion = compileKotlinJvm.kotlinJavaToolchain.javaVersion.orNull
231+
if (javaVersion?.isJava9Compatible == true) {
232+
logger.info("Module-info checking is enabled; $compileKotlinJvm is compiled using Java $javaVersion")
233+
compileKotlinJvm.source(sourceDir)
234+
} else {
235+
logger.info("Module-info checking is disabled")
236+
}
237+
238+
// Set the task outputs and destination dir
239+
outputs.dir(targetDir)
240+
destinationDir = targetDir
241+
242+
// Configure JVM compatibility
243+
sourceCompatibility = JavaVersion.VERSION_1_9.toString()
244+
targetCompatibility = JavaVersion.VERSION_1_9.toString()
245+
246+
// Set the Java release version.
247+
options.release.set(9)
248+
249+
// Ignore warnings about using 'requires transitive' on automatic modules.
250+
options.compilerArgs.add("-Xlint:-requires-transitive-automatic")
251+
252+
// Patch the compileKotlinJvm output classes into the compilation so exporting packages works correctly.
253+
options.compilerArgs.addAll(listOf("--patch-module", "$moduleName=${compileKotlinJvm.destinationDir}"))
254+
255+
// Use the classpath of the compileKotlinJvm task.
256+
// Also ensure that the module path is used instead of classpath.
257+
classpath = compileKotlinJvm.classpath
258+
modularity.inferModulePath.set(true)
259+
260+
// Configure the JAR task so that it will include the compiled module-info class file.
261+
getByName<Jar>("jvmJar") {
262+
dependsOn(this@create)
263+
manifest {
264+
attributes("Multi-Release" to true)
265+
}
266+
from(targetDir) {
267+
into("META-INF/versions/9/")
268+
}
269+
}
270+
}
208271
}
209272

210273
task("downloadWindowsZonesMapping") {

core/jvm/java9/module-info.java

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module kotlinx.datetime {
2+
requires transitive kotlin.stdlib;
3+
requires transitive static kotlinx.serialization.core;
4+
5+
exports kotlinx.datetime;
6+
exports kotlinx.datetime.serializers;
7+
}

0 commit comments

Comments
 (0)