I'm building a java project with maven. I want to make sure several things:
How should I configure the maven-compiler-plugin? thanks.
the original repo is at https://github.com/cyanpotion/SDL_GameControllerDB_Util
right now I can pass 2 and 3, but the output jar seems cannot run on jre8.
A multi-release jar can be used to accomplish this purpose; however, if you are only after Jigsaw module support, a dual compilation configuration of Java 8 and 9 with the maven-compiler-plugin
is sufficient (demonstrated below).
The following is a build configuration that is able to maintain JRE 8 support, but is compatible with being used as a module in JRE 9+. This can be tweaked to support a project as far back as JRE 1.6, if necessary.
Overview of the following build configuration:
$JAVA_HOME
JDK 9+ so that module-info.java
can be compiled and validated against the sources (ensures that all module dependencies are correctly referenced).default-compile
execution to NO-OP. By specifying <release>8</release>
(or target
/source
flags), some IDEs during Maven auto-importation (tested with IntelliJ) will assume the language level for this project is Java 8, and produce errors about the project's module-info.java
.module-info.java
) for Java 9; this ensures that the module-info.java
includes any dependencies used without the project sources.module-info.java
) for Java 8, overwriting all previously compiled Java 9 classes with Java 8 classes; this means the only Java 9 class (class level 53+) will be module-info.class
. All other classes should now be executable on a compliant JRE 8.Notes:
module-info.java
in another source directory (e.g. src/main/java9
) and configuring a multi-release JAR (see the first link at the beginning of this message). Note that for proper IDE auto-importation and marking this additional Java 9 source directory correctly, a NO-OP execution with org.codehaus.mojo:build-helper-maven-plugin
can be used.module-info.java
will have Java 9 support, all other classes are limited to classes/methods/fields/code available in JDK/JRE 8.module-info.class
. Some older variants of the default Maven plugins do not have sufficient support for modules.<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>