Gradle官方引用了使用JDK9 +构建Java应用程序以在Java 8环境中运行的方法是使用标志--release 8
:
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
我尝试这样做,但是编译器仍然会抛出错误:
module myapp.main {
^
(use -source 9 or higher to enable modules)
1 error
:compileJava FAILED
根据该文档和许多stackoverflow文章(如this),编译器应该在定位8时忽略模块文件,但它没有。那是为什么?
Gradle代码:
compileJava {
dependsOn(':compileKotlin')
options.compilerArgs.addAll(['--release', '8'])
doFirst {
println classpath.asPath
options.compilerArgs += [
'--module-path', classpath.asPath,
]
classpath = files()
}
}
答案 0 :(得分:0)
--release
release
针对特定VM版本的公共,支持和记录的API进行编译。支持的
release
目标是6
,7
,8
和9
。
我读到这意味着编译器将处理在以后版本中引入的任何公共方法和类,就像它们不存在一样。例如,如果使用--release 8
编译的代码导入或引用java.lang.Module,编译器将发出错误,指出该类不存在。
我没有看到Gradle文档的任何部分声明--release
是目标Java 8 JVM的首选或官方方式。我只看到使用--release
作为如何添加自定义编译器选项的示例的示例。
归结为,如果你想为Java 8编译,你需要排除module-info.java。
如果你想要一个既可以作为模块的单个.jar,又可以像Java 8一样对待常规.jar,你可能需要一个multi-release jar。
多版本jar是Java 9引入的概念。如果忽略除清单之外的.jar中的所有META-INF条目,它看起来就像9之前的.jar。没有module-info,没有Java 9+类文件。
所有Java 9版本都存在于.jar文件中的META-INF/versions/9
下。例如,.jar文件中的某些条目可能是:
META-INF/versions/9/module-info.class
META-INF/versions/9/com/example/myapp/MyApplication.class
要向Java 9+运行时发出信号,表明.jar是一个多版本.jar,你将这一个清单条目添加到.jar中:
Multi-Release: true
至于如何在Gradle中完成所有这些操作,this blog建议您创建source sets。我没有使用Gradle构建,因此从文档中我不完全清楚如何做到这一点。从How to make Multi-Release JAR Files with Gradle?的赞成票数和答案数来看,似乎其他人也不清楚。
答案 1 :(得分:0)
这个问题已经存在了将近一年,但也许仍然会有所帮助:VGR的答案对于为什么module-info.java
不会被--release 8
标志忽略是绝对正确的。 / p>
关于编译主要Java 8类和Java 9 module-info.java
的方法时, Gradle Modules Plugin 自{{ 3}}。可以在此处找到更多详细信息: