Does Kotlin 1.2.10 and Java 9 have opposite rules regarding automatic modules?

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 these dependencies in my Kotlin source ( Foo.kt , Bar.kt , ...).

Everything works hunky-dory if I write my module-info.java like this:

 module my.module { requires kotlin.stdlib; exports my.module.pkg; } 

and if I put all my compile time dependencies before javac during the compileJava task using this method .

However, if I enable -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 there shouldn't be a requires clause for it.

But if I remove the requires clause to make javac happy, it makes kotlinc even more evil than javac (I get an error message not 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 this by editing my compileKotlin task this way:

 compileKotlin { doFirst { kotlinOptions.freeCompilerArgs = ['-Xallow-kotlin-package'] } } 

But this only leads to MORE errors during the compileKotlin task, everyone looks like this:

 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 get compileKotlin to take the module path, not the class path, by adding "-Xmodule-path=${classpath.asPath}" to freeCompilerArgs and setting the classpath as empty, the Kotlin compiler will not find anything at all, and I end up with zillions of unresolved link errors!

Why does the Kotlin compiler tell me that I must have requires kotlin.stdlib; when does the Java compiler say otherwise? How can I get Kotlin and Java to work together to create a Java 9 module?

+5
source share
1 answer

If you are creating a Java 9 module in Kotlin, you need to declare requires kotlin.stdlib in module-info.java in order to satisfy the runtime dependencies of the compiled Kotlin code in addition to the explicit dependencies on the standard library API.

javac warns you about the need to use an automatic module when you turn on lint, since automatic modules have some potential disadvantages compared to regular modules. Until the standard library is compiled as a regular module, you will have to deal with this warning.

-Xallow-kotlin-package compiler flag allows you to skip require kotlin.stdlib , since it is intended to be used only when compiling the standard library. Obviously, if you specify this flag and omit this requirement, you will not be able to use any API from the standard library, so this is not an option for you.

0
source

Source: https://habr.com/ru/post/1274302/