Kotlin 1.2.10和Java 9对自动模块有相反的规定吗?

我有一个使用Kotlin Gradle插件的Gradle项目。 我想建立一个Java 9模块,所以我的目录结构如下所示:

src/main/java/ - module-info.java src/main/kotlin/ - Foo.kt - Bar.kt build.gradle ... 

我的build.gradle声明以下依赖项:

 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" } 

我在我的Kotlin源码( Foo.ktBar.kt ,…)中使用所有这些依赖关系。

一切工作hunky-dory,如果我写我的module-info.java像这样:

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

如果我在compileJava任务中使用这种技术将所有的编译时间依赖关系提供给javac

但是,如果我在compileJava任务(编译module-info.java )期间打开-Xlint:all的Java编译器,我会得到以下警告:

 /path/to/my.module/src/main/java/module-info.java:26: warning: requires directive for an automatic module requires kotlin.stdlib; ^ 

所以在这里我们有Java编译器, javac抱怨kotlin.stdlib是一个自动模块,所以我不应该有一个kotlin.stdlib子句。

但是,如果我删除了requires条款,使javac高兴,这使得kotlinc甚至比javac更愤怒(我得到一个错误不是一个警告):

 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'. 

现在我可以通过编辑我的compileKotlin任务来解决这个问题:

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

但是这只会导致compileKotlin任务期间更多的错误,看起来像这样:

 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 

然后,如果我试图通过向"-Xmodule-path=${classpath.asPath}"添加"-Xmodule-path=${classpath.asPath}"并将classpath设置为空来强制compileKotlin采用模块路径而不是类"-Xmodule-path=${classpath.asPath}" ,则Kotlin编译器无法在所有,我最终与无数未解决的参考错误!

为什么Kotlin编译器告诉我必须requires kotlin.stdlib; 当Java编译器说相反? 我如何让Kotlin和Java一起工作来生成Java 9模块?

如果您是在Kotlin中编写Java 9模块,则requires kotlin.stdlib在您的module-info.java中声明requires kotlin.stdlib ,以便除了对标准库API的显式依赖关系外,还可以满足已编译的Kotlin代码的运行时依赖关系。

当启用lint时, javac警告您需要一个自动模块,因为与普通模块相比,自动模块有一些潜在的缺点 。 在标准库被编译为正常模块之前,你必须处理这个警告。

-Xallow-kotlin-package编译器标志允许你省略require kotlin.stdlib ,因为它只打算在标准库本身编译时使用。 显然,如果你指定了这个标志并且忽略了这个要求,你将不能使用标准库中的任何API,所以这对你来说不是一个真正的选择。