kotlinx.serialization icon indicating copy to clipboard operation
kotlinx.serialization copied to clipboard

Ambiguous JPMS module reference in maven projects

Open fzhinkin opened this issue 11 months ago • 3 comments

In maven projects, published "umbrella" artifacts (like "kotlinx-serialization-json") works as a gateway to corresponding -jvm artifacts. The former do not have a JPMS module bundled inside, so the module name is inferred from the artifact name. As a result, there are two artifacts providing the same module:

  • kotlinx-serialization-json provides kotlinx.serialization.json as it was inferred from the module name.
  • kotlinx-serialization-json-jvm provides kotlinx.serialization.json, well, because it actually provides it.

To Reproduce

Here's a reproducer: https://github.com/fzhinkin/kotlinx-serialization-jpms-conflict

$ mvm compile
...
[WARNING] /Users/filipp.zhinkin/.m2/repository/org/jetbrains/kotlinx/kotlinx-serialization-json-jvm/1.8.0/kotlinx-serialization-json-jvm-1.8.0.jar: (-1, -1) The root is ignored because a module with the same name 'kotlinx.serialization.json' has been found earlier on the module path at: /Users/filipp.zhinkin/.m2/repository/org/jetbrains/kotlinx/kotlinx-serialization-json/1.8.0/kotlinx-serialization-json-1.8.0.jar
[ERROR] /Users/filipp.zhinkin/Development/kotlinx-serialization-jmps-conflict/src/main/kotlin/Dummy.kt: (4, 30) Unresolved reference 'json'.
[ERROR] /Users/filipp.zhinkin/Development/kotlinx-serialization-jmps-conflict/src/main/kotlin/Dummy.kt: (10, 33) Unresolved reference 'Json'.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE

Expected behavior

"Umbrella" artifacts like kotlinx-serialization-core or kotlinx-serialization-json should provide some JPMS modules that won't clash with modules provided by actual ***-jvm artifacts.

fzhinkin avatar Jan 08 '25 18:01 fzhinkin

See corresponding issue in coroutines: https://github.com/Kotlin/kotlinx.coroutines/issues/3842

fzhinkin avatar Jan 08 '25 18:01 fzhinkin

In both of these libraries this is a result of your own configuration. See here and there.

Instead of making the metadata/common artifact depend on the JVM one, have you considered a relocation pom instead?

Another option would be to publish the JVM artifacts using the unsuffixed artifactId and move the metadata/common artifact to have a -common suffix. The Gradle module metadata will still be published with the unsuffixed artifact allowing both Maven and Gradle users to continue to consume it. This is what the stdlib does: https://search.maven.org/search?q=kotlin-stdlib.

JakeWharton avatar Jan 08 '25 18:01 JakeWharton

Changing the way artifacts are published is out of this issue's scope, and we'll discuss it separately.

Libraries pretending that an artifact without any platform specific suffix is the JVM-specific one are doing so for compatibility reasons, mostly. Although, the necessity to specify -jvm suffix in pom.xml for every other Kotlin library bugs me.

Relocation POMs might be a solution, but for the time being, adding a single line to the metadata JAR manifest looks easier and safer.

fzhinkin avatar Nov 10 '25 18:11 fzhinkin