如何在同时支持 jigsaw 和 jre 8 的情况下使用 maven?

Xen*_*ess 4 java maven java-platform-module-system java-8 java-9

我正在用 maven 构建一个 java 项目。我想确定几件事:

  1. 构建的 jar 可以在 jre8 上运行。
  2. 构建的 jar 可以在 jre9 上运行,带有模块/拼图。
  3. 构建的 jar 可以放在 maven central 上。

我应该如何配置 maven-compiler-plugin?谢谢。

原始存储库位于https://github.com/cyanpotion/SDL_GameControllerDB_Util

现在我可以通过 2 和 3,但是输出 jar 似乎无法在 jre8 上运行。

con*_*ion 5

多释放罐可用于达到这个目的; 但是,如果您只支持 Jigsaw 模块,则 Java 8 和 9 的双重编译配置maven-compiler-plugin就足够了(如下所示)。

以下是能够维持 JRE 8 支持但兼容在 JRE 9+ 中用作模块的构建配置。如有必要,可以对其进行调整以支持早至 JRE 1.6 的项目。

以下构建配置的概述

  • 强制执行$JAVA_HOMEJDK 9+,以便module-info.java可以针对源进行编译和验证(确保正确引用所有模块依赖项)。
  • default-compile执行更改为 NO-OP。通过指定<release>8</release>(或target/source标志),Maven 自动导入(使用 IntelliJ 测试)期间的某些 IDE 将假定此项目的语言级别为 Java 8,并产生有关项目的module-info.java.
  • 编译module-info.javaJava 9 的所有源代码(包括);这可确保包含在module-info.java没有项目源的情况下使用的任何依赖项。
  • 为 Java 8编译所有源(不包括 module-info.java),用 Java 8 类覆盖所有以前编译的 Java 9 类;这意味着唯一的 Java 9 类(类级别 53+)将是module-info.class. 所有其他类现在应该可以在兼容的 JRE 8 上执行。

注意事项

  • 需要注意的是,这将编译两次源代码,一次用于 Java 8,另一次用于 Java 9。这可能会显着增加大型项目的构建时间(但对于较小的项目可以忽略不计)。这可以通过放置module-info.java在另一个源目录(例如src/main/java9)并配置多版本 JAR 来解决(请参阅此消息开头的第一个链接)。请注意,为了正确地自动导入 IDE 并正确标记这个额外的 Java 9 源目录,org.codehaus.mojo:build-helper-maven-plugin可以使用NO-OP 执行。
  • module-info.java支持 Java 9,所有其他类仅限于 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>
Run Code Online (Sandbox Code Playgroud)