Older projects with module-info

For projects that want to be compatible with older versions of Java (i.e 1.8 or below), but also want to provide a module-info.java for Java 9 projects must be aware that they need to call javac twice: the module-info.java must be compiled with release=9, while the rest of the sources must be compiled with a lower version of source/target.

The preferred way to do this is by having 2 execution blocks are described below. JDK 9 only supports compilations for Java 6 and above, so projects wanting to be compatible with Java 5 or below need to use two different JDKs. With toolchains it is quite easy to achieve this. Be aware that you will need at least Maven 3.3.1 to specify a custom jdkToolchain in your plugin configuration. You could add a jdkToolchain to do base-compile execution-block as well referring to JDK 5.

  1. <project>
  2. [...]
  3. <build>
  4. [...]
  5. <plugins>
  6. <plugin>
  7. <groupId>org.apache.maven.plugins</groupId>
  8. <artifactId>maven-compiler-plugin</artifactId>
  9. <version>3.6.1</version>
  10. <executions>
  11. <execution>
  12. <id>default-compile</id>
  13. <configuration>
  14. <!-- compile everything to ensure module-info contains right entries -->
  15. <!-- required when JAVA_HOME is JDK 8 or below -->
  16. <jdkToolchain>
  17. <version>9</version>
  18. </jdkToolchain>
  19. <release>9</release>
  20. </configuration>
  21. </execution>
  22. <execution>
  23. <id>base-compile</id>
  24. <goals>
  25. <goal>compile</goal>
  26. </goals>
  27. <!-- recompile everything for target VM except the module-info.java
  28. <configuration>
  29. <excludes>
  30. <exclude>module-info.java</exclude>
  31. </excludes>
  32. </configuration>
  33. </execution>
  34. </executions>
  35. <!-- defaults for compile and testCompile -->
  36. <configuration>
  37. <!-- jdkToolchain required when JAVA_HOME is JDK 9 or above -->
  38. <jdkToolchain>
  39. <version>[1.5,9)</version>
  40. </jdkToolchain>
  41. <source>1.5</source>
  42. <target>1.5</target>
  43. </configuration>
  44. </plugin>
  45. </plugins>
  46. [...]
  47. </build>
  48. [...]
  49. </project>

In case you want the project to be Java 6 compatible, the easiest to do this is to use Java 9 for both execution blocks. You can use the maven-toolchain-plugin to specify the shared JDK (supported since Maven 2.0.9) or a custom jdkToolchain (supported since Maven 3.3.1) and refer to the JDK 9 installation on your system. Or simply use Java 9 as the runtime for Maven by setting JAVA_HOME=/path/to/jdk-9.

  1. <project>
  2. [...]
  3. <build>
  4. [...]
  5. <plugins>
  6. <plugin>
  7. <groupId>org.apache.maven.plugins</groupId>
  8. <artifactId>maven-compiler-plugin</artifactId>
  9. <version>3.6.1</version>
  10. <executions>
  11. <execution>
  12. <id>default-compile</id>
  13. <configuration>
  14. <!-- compile everything to ensure module-info contains right entries -->
  15. <release>9</release>
  16. </configuration>
  17. </execution>
  18. <execution>
  19. <id>base-compile</id>
  20. <goals>
  21. <goal>compile</goal>
  22. </goals>
  23. <!-- recompile everything for target VM except the module-info.java
  24. <configuration>
  25. <excludes>
  26. <exclude>module-info.java</exclude>
  27. </excludes>
  28. </configuration>
  29. </execution>
  30. </executions>
  31. <!-- defaults for compile and testCompile -->
  32. <configuration>
  33. <!-- Only required when JAVA_HOME isn't at least Java 9 and when haven't configured the maven-toolchains-plugin -->
  34. <jdkToolchain>
  35. <version>9</version>
  36. </jdkToolchain>
  37. <release>6</release>
  38. </configuration>
  39. </plugin>
  40. </plugins>
  41. [...]
  42. </build>
  43. [...]
  44. </project>