-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add explicit module-info for JPMS compatibility #135
Conversation
After some more testing I observed that the Kotlin compiler does not check if the correct To circumvent this problem altogether I took an alternative route where the
Note that I updated the version of I also had to update the kotlin version to
|
I reworked this branch / PR based on the comments from Kotlin/kotlinx.serialization#1624.
|
A similar solution has been merged in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR.
We'd like to pursue a slightly different approach in this project than in kotlinx-serialization
:
- first, we'll continue building and testing the JVM target with JDK 8 to avoid accidentally using a newer API or depending on a newer behavior.
module-info.java
should be compiled in a separate java compilation task that uses another sufficient JDK with the-release 9
option- the result of that compilation shall be added into the resulting jar in the
META-INF/versions/9
directory - we'll be using Gradle toolchains feature to detect or provision the required JDKs: JDK 8 for the main compilation and tests and JDK 11 for compiling module-info. This work has started in the PR Use java toolchains to setup JDK 8 path #155.
Could you modify the PR according to the points above?
core/jvm/src/module-info.java
Outdated
@@ -0,0 +1,7 @@ | |||
module kotlinx.datetime { | |||
requires transitive kotlin.stdlib; | |||
requires transitive static kotlinx.serialization.core; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well spotted here that we need requires static
because the dependency is compile only. Does it mean that a client module has to require kotlinx.serialization.core
(or another module that requires it transitively) in order to use this aspect of kotlinx.datetime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes and no. Normally a modular application won't start if 1 of the required modules isn't on the module path.
Because of the requires static
an application will start anyway, ignoring the 'missing' module.
Obviously if you want to use the datetime serializers you will have to explicitly require kotlinx.serialization.core
anyway because all the serializer interfaces and logic is in there.
buildSrc/build.gradle.kts
Outdated
|
||
val kotlinVersion = file("../gradle.properties").inputStream().use { | ||
Properties().apply { load(it) } | ||
}.getProperty("kotlinVersion") ?: throw IllegalStateException("Property 'kotlinVersion' must be defined in ../gradle.properties") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach significantly limits the ways how kotlinVersion
can be defined. Due to that we'd like to avoid having the code that depends on kotlin plugin in buildSrc, especially considering that it is only needed in one subproject so far.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally agree, this was actually the most annoying part. I just wished that the buildSrc
project had access to the properties of the root project, but that is unfortunately not the case.
Anyway, I'll move the relevant code to an (simplified) inline block inside the core
subproject, since that is the only place that uses this.
The problem was in an invalid resources directory path with a trailing space.
@ilya-g I processed your feedback and moved the Gradle configuration to an inline block in the Also note this line, which can be removed once #155 is merged: |
@ilya-g updated this PR per your suggestions. Both the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good. A small polishing is required, but I'll do it myself after merging.
Merged. The resulting commits are e6401c6~1...bbbbd9c |
In this pull request I added a
module-info.java
file so thekotlinx.datetime
library can be used in Java JPMS (Jigsaw) projects. I also extended thebuild.gradle.kts
script so it does a separate compilation of themodule-info.java
file.To maintain backwards compatibility with Java 8, I marked the resulting JAR as a multi-release JAR with the
module-info.class
moved toMETA-INF/versions/9/module-info.class
which is similar as how it's done in the Kotlin stdlib. See https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jdk8/build.gradle#L80, https://github.com/JetBrains/kotlin/blob/master/buildSrc/src/main/kotlin/LibrariesCommon.kt#L22 and https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jdk8/java9/module-info.java for more details.Note that moving the
module-info.class
was / is not really necessary for JPMS to work, but I believe it's a bit cleaner than just adding the compiledmodule-info.class
to the root of the JAR.This change allows bundling projects using
jlink
, which requires that all dependencies are explicit JPMS (Jigsaw) modules. That means all JAR's must contain amodule-info.class
, automatic modules don't work withjlink
.In 1 of my own projects I am trying to bundle an OpenJFX / TornadoFX application, which currently works using a SNAPSHOT version of this branch.
Note that at least JDK 9 is needed to build this branch (for compiling the
module-info.java
file). Existing code can of course be compiled using a Java 8 target. This PR is closely related to Kotlin/kotlinx.serialization#1624.