I have a Gradle project using the Kotlin Gradle plugin. I want to build a Java 9 module, so my directory structure looks like this:
src/main/java/
- module-info.java
src/main/kotlin/
- Foo.kt
- Bar.kt
build.gradle
...
My build.gradle
declares the following dependencies:
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.10"
compile "org.jetbrains.kotlin:kotlin-reflect:1.2.10"
compile "org.junit.jupiter:junit-jupiter-api:5.0.2"
}
and I use all of these dependencies in my Kotlin source (Foo.kt
, Bar.kt
, ...).
Everything works hunky-dory if I write my module-info.java
like so:
module my.module {
requires kotlin.stdlib;
exports my.module.pkg;
}
and if I supply all my compile-time dependencies to javac
during the compileJava
task using this technique.
However if I turn on -Xlint:all
for the Java compiler during the compileJava
task (to compile module-info.java
), I get the following warnings:
/path/to/my.module/src/main/java/module-info.java:26: warning: requires directive for an automatic module
requires kotlin.stdlib;
^
So here we have the Java compiler, javac
complaining that kotlin.stdlib
is an automatic module so I shouldn't have a requires
clause for it.
But if I delete the requires
clause to make javac
happy, it makes kotlinc
even angrier than javac
was (I get an error not a warning):
e: /path/to/my.module/src/main/java/module-info.java: The Kotlin standard library is not found in the module graph. Please ensure you have the 'requires kotlin.stdlib' clause in your module definition
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':my.module:compileKotlin'.
Now I can fix that, too, by editing my compileKotlin
task thus:
compileKotlin {
doFirst {
kotlinOptions.freeCompilerArgs = ['-Xallow-kotlin-package']
}
}
But this only leads to MORE errors during the compileKotlin
task, all looking like this one:
e: /path/to/my.module/src/main/kotlin/Foo.kt: (27, 30): Symbol is declared in module 'org.junit.jupiter.api' which current module does not depend on
And then if I try to force compileKotlin
to take a module path rather than a classpath by adding "-Xmodule-path=${classpath.asPath}"
to freeCompilerArgs
and setting classpath
to be empty, the Kotlin compiler can't find anything at all, and I end up with zillions of unresolved reference errors!
Why is the Kotlin compiler telling me I have to have requires kotlin.stdlib;
when the Java compiler says the opposite? How can I get Kotlin and Java to work together to produce a Java 9 module?
requires
directive fororg.junit.jupiter.api
? maybe this is what causes the last error from the kotlin compiler – Lotsorg.junit.jupiter.api
into themodule-info.java
as arequires
does get rid of the unresolved symbol reference errors. HOWEVER, again, it generates an-Xlint:all
warning fromjavac
which doesn't wantrequires
on automatic modules. So again it seems like Kotlin and Java are enforcing different rules here. – Sarracenia-Xallow-kotlin-package
flag? – Lots-Xallow-kotlin-package
allows me to do is omitrequires kotlin.stdlib;
from mymodule-info.java
thus saving onejavac
warning. – Sarracenia