如何在 jigsaw 和 jre 8 支持下使用 maven?
How to use maven with both jigsaw and jre 8 support?
我正在使用 Maven 构建一个 java 项目。
我想确定几件事:
- 构建的 jar 可以在 jre8 上 运行。
- 构建的 jar 可以在 jre9 上 运行,module/jigsaw。
- 构建的jar可以放在maven central上。
我应该如何配置maven-compiler-plugin?
谢谢。
原始仓库位于 https://github.com/cyanpotion/SDL_GameControllerDB_Util
现在我可以通过 2 和 3,但输出 jar 似乎不能 运行 在 jre8 上。
一个multi-release jar可以用来完成这个目的;但是,如果您仅在 Jigsaw 模块支持之后,Java 8 和 9 以及 maven-compiler-plugin
的双编译配置就足够了(如下所示)。
以下是能够保持 JRE 8 支持但兼容在 JRE 9+ 中用作模块的构建配置。如有必要,可以对其进行调整以支持最早可追溯到 JRE 1.6 的项目。
以下构建配置概述:
- 强制执行
$JAVA_HOME
JDK 9+ 以便 module-info.java
可以根据源代码进行编译和验证(确保正确引用所有模块依赖项)。
- 将
default-compile
执行更改为 NO-OP。通过指定 <release>8</release>
(或 target
/source
标志),Maven auto-importation(使用 IntelliJ 测试)期间的某些 IDEs 将采用该项目的语言级别是 Java 8,并产生有关项目的 module-info.java
. 的错误
- 为 Java 9 编译所有源代码(包括
module-info.java
);这确保了 module-info.java
包含在没有项目源的情况下使用的任何依赖项。
- 为Java8编译所有源代码(不包括
module-info.java
),覆盖所有以前编译的Java9classes Java 8 classes;这意味着唯一的 Java 9 class(class 53+ 级)将是 module-info.class
。所有其他 classes 现在应该可以在兼容的 JRE 8 上执行。
备注:
- 需要注意的是,这将编译源代码 两次 ,一次用于 Java 8,另一次用于 Java 9。这可能会显着增加更大的构建时间项目(但对于较小的项目可以忽略不计)。这可以通过将
module-info.java
放在另一个源目录(例如 src/main/java9
)并配置 multi-release JAR(请参阅本消息开头的第一个 link)来解决。请注意,为了正确 IDE auto-importation 并正确标记此额外的 Java 9 源目录,可以使用带有 org.codehaus.mojo:build-helper-maven-plugin
的 NO-OP 执行。
- 只有
module-info.java
将支持 Java 9,所有其他 class 仅限 classes/methods/fields/code 在 JDK/JRE 8 中可用。
- 如果某些工具不支持 Java 9
module-info.class
,则可能需要在您的项目配置中对其进行更新。默认 Maven 插件的一些旧变体对模块的支持不足。
<build>
<plugins>
<!-- ensure the project is compiling with JDK 9+ -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<id>enforce-jdk9</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[1.9,)</version>
<message>JDK 9+ is required for compilation</message>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<!-- compile sources -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<executions>
<!-- disable default phase due to fixed id and position in lifecycle -->
<execution>
<id>default-compile</id>
<phase>none</phase>
<!-- specify source/target for IDE integration -->
<configuration>
<release>9</release>
</configuration>
</execution>
<!-- compile sources with Java 9 to generate and validate module-info.java -->
<execution>
<id>java-9-module-compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>9</release>
</configuration>
</execution>
<!-- recompile sources as Java 8 to overwrite Java 9 class files, except module-info.java -->
<execution>
<id>java-8-compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<!-- specify JDK 9+ release flag to ensure no classes/methods later than Java 8 are used accidentally -->
<release>8</release>
<!-- exclude module-info.java from the compilation, as it is unsupported by Java 8 -->
<excludes>
<exclude>module-info.java</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
我做到了。查看我的项目,the IPAddress Java library。您使用 Java 9 编译器级别进行编译,然后使用 Java 8 编译级别重新编译除 module-info.java 之外的所有内容。所以您有一个 Java 8带有 Java 9 module-info 的罐子。您可以在 GitHub.
上的我的 ant xml 脚本中看到编译命令
最初 Android studio 有一个问题,现在已经解决了,不会忽略 module-info。最近的 Android 工作室版本很好,所有 Java 平台和环境也很好。 Java 9 jres 及以上会识别 module-info,Java 8 不会,Java 8 及更早版本将忽略它。
我的jar也在maven central里面,满足你的3个要求。使用 Java 8 或更高版本的 jres.
在您的开发环境中试用它以查看它是否有效
Multi-release 罐子不是必需的,不值得麻烦。
当我研究同样的问题时,我发现 Apache 项目正在使用同样的解决方案,所以我不是唯一一个这样做的人。
我正在使用 Maven 构建一个 java 项目。 我想确定几件事:
- 构建的 jar 可以在 jre8 上 运行。
- 构建的 jar 可以在 jre9 上 运行,module/jigsaw。
- 构建的jar可以放在maven central上。
我应该如何配置maven-compiler-plugin? 谢谢。
原始仓库位于 https://github.com/cyanpotion/SDL_GameControllerDB_Util
现在我可以通过 2 和 3,但输出 jar 似乎不能 运行 在 jre8 上。
一个multi-release jar可以用来完成这个目的;但是,如果您仅在 Jigsaw 模块支持之后,Java 8 和 9 以及 maven-compiler-plugin
的双编译配置就足够了(如下所示)。
以下是能够保持 JRE 8 支持但兼容在 JRE 9+ 中用作模块的构建配置。如有必要,可以对其进行调整以支持最早可追溯到 JRE 1.6 的项目。
以下构建配置概述:
- 强制执行
$JAVA_HOME
JDK 9+ 以便module-info.java
可以根据源代码进行编译和验证(确保正确引用所有模块依赖项)。 - 将
default-compile
执行更改为 NO-OP。通过指定<release>8</release>
(或target
/source
标志),Maven auto-importation(使用 IntelliJ 测试)期间的某些 IDEs 将采用该项目的语言级别是 Java 8,并产生有关项目的module-info.java
. 的错误
- 为 Java 9 编译所有源代码(包括
module-info.java
);这确保了module-info.java
包含在没有项目源的情况下使用的任何依赖项。 - 为Java8编译所有源代码(不包括
module-info.java
),覆盖所有以前编译的Java9classes Java 8 classes;这意味着唯一的 Java 9 class(class 53+ 级)将是module-info.class
。所有其他 classes 现在应该可以在兼容的 JRE 8 上执行。
备注:
- 需要注意的是,这将编译源代码 两次 ,一次用于 Java 8,另一次用于 Java 9。这可能会显着增加更大的构建时间项目(但对于较小的项目可以忽略不计)。这可以通过将
module-info.java
放在另一个源目录(例如src/main/java9
)并配置 multi-release JAR(请参阅本消息开头的第一个 link)来解决。请注意,为了正确 IDE auto-importation 并正确标记此额外的 Java 9 源目录,可以使用带有org.codehaus.mojo:build-helper-maven-plugin
的 NO-OP 执行。 - 只有
module-info.java
将支持 Java 9,所有其他 class 仅限 classes/methods/fields/code 在 JDK/JRE 8 中可用。 - 如果某些工具不支持 Java 9
module-info.class
,则可能需要在您的项目配置中对其进行更新。默认 Maven 插件的一些旧变体对模块的支持不足。
<build>
<plugins>
<!-- ensure the project is compiling with JDK 9+ -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<id>enforce-jdk9</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[1.9,)</version>
<message>JDK 9+ is required for compilation</message>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<!-- compile sources -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<executions>
<!-- disable default phase due to fixed id and position in lifecycle -->
<execution>
<id>default-compile</id>
<phase>none</phase>
<!-- specify source/target for IDE integration -->
<configuration>
<release>9</release>
</configuration>
</execution>
<!-- compile sources with Java 9 to generate and validate module-info.java -->
<execution>
<id>java-9-module-compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>9</release>
</configuration>
</execution>
<!-- recompile sources as Java 8 to overwrite Java 9 class files, except module-info.java -->
<execution>
<id>java-8-compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<!-- specify JDK 9+ release flag to ensure no classes/methods later than Java 8 are used accidentally -->
<release>8</release>
<!-- exclude module-info.java from the compilation, as it is unsupported by Java 8 -->
<excludes>
<exclude>module-info.java</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
我做到了。查看我的项目,the IPAddress Java library。您使用 Java 9 编译器级别进行编译,然后使用 Java 8 编译级别重新编译除 module-info.java 之外的所有内容。所以您有一个 Java 8带有 Java 9 module-info 的罐子。您可以在 GitHub.
上的我的 ant xml 脚本中看到编译命令最初 Android studio 有一个问题,现在已经解决了,不会忽略 module-info。最近的 Android 工作室版本很好,所有 Java 平台和环境也很好。 Java 9 jres 及以上会识别 module-info,Java 8 不会,Java 8 及更早版本将忽略它。
我的jar也在maven central里面,满足你的3个要求。使用 Java 8 或更高版本的 jres.
在您的开发环境中试用它以查看它是否有效Multi-release 罐子不是必需的,不值得麻烦。
当我研究同样的问题时,我发现 Apache 项目正在使用同样的解决方案,所以我不是唯一一个这样做的人。