Java 9 --release标志似乎在Gradle中不起作用

问题描述 投票:2回答:2

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()
    }
}
java gradle compiler-errors java-9
2个回答
0
投票

来自the javac documentation

--release release

针对特定VM版本的公共,支持和记录的API进行编译。支持的release目标是6789

我读到这意味着编译器将处理在更高版本中引入的任何公共方法和类,就像它们不存在一样。例如,如果使用--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。没有模块信息,没有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?的upvotes数量和答案数量来看,似乎其他人也不清楚。


0
投票

这个问题已经差不多一年了,但也许它仍然会有所帮助:VGR的回答是绝对正确的,为什么module-info.java不会被--release 8旗子忽略。

当谈到如何编译主Java 8类+ Java 9 module-info.java时,自版本1.5.0以来,Gradle Modules插件现在支持此功能。更多详情可在这找到:

© www.soinside.com 2019 - 2024. All rights reserved.