Maven and Java multi-version modules
Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Wouldn’t that be just awesome?
Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, or Play Framework.
So, enjoy spending your time on the things you love rather than fixing performance issues in your production system on a Saturday night!
Introduction
In this article, you are going to learn how to configure Maven to choose a specific Java version when the OS has multiple Java versions installed.
For instance, FlexyPool uses Java 8 for all modules, except for the flexy-pool-core-java9
module that needs to be built using Java 9.
Using Maven Toolchains to define multiple Java versions
To use multiple Java versions, you need to use Maven Toolchains, which require you to create a toolchains.xml
file in your ~/.m2
Maven folder, containing all Java versions installed on your machine:
<toolchains> <toolchain> <type>jdk</type> <provides> <id>Java17</id> <version>17</version> </provides> <configuration> <jdkHome>${env.JAVA_HOME_17}</jdkHome> </configuration> </toolchain> <toolchain> <type>jdk</type> <provides> <id>Java9</id> <version>9</version> </provides> <configuration> <jdkHome>${env.JAVA_HOME_9}</jdkHome> </configuration> </toolchain> <toolchain> <type>jdk</type> <provides> <id>Java8</id> <version>8</version> </provides> <configuration> <jdkHome>${env.JAVA_HOME_8}</jdkHome> </configuration> </toolchain> <toolchain> <type>jdk</type> <provides> <id>Java7</id> <version>7</version> </provides> <configuration> <jdkHome>${env.JAVA_HOME_7}</jdkHome> </configuration> </toolchain> <toolchain> <type>jdk</type> <provides> <id>Java6</id> <version>6</version> </provides> <configuration> <jdkHome>${env.JAVA_HOME_6}</jdkHome> </configuration> </toolchain> </toolchains>
The JAVA_HOME_17
, JAVA_HOME_9
, JAVA_HOME_8
, JAVA_HOME_7
, JAVA_HOME_6
environment variables are configured so that they reference the path where the associated Java version is installed.
The parent pom.xml Maven configuration defining a default Java version
The parent pom.xml
Maven configuration file defines the global Java version settings
<properties> <jdk.version>8</jdk.version> ... </properties>
Now, we need to instruct both the compiler and the test plugins to use the configured java version.
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-toolchains-plugin</artifactId> <version>1.1</version> <executions> <execution> <goals> <goal>toolchain</goal> </goals> </execution> </executions> <configuration> <toolchains> <jdk> <version>${jdk.version}</version> </jdk> </toolchains> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven-compiler-plugin.version}</version> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> <showDeprecation>true</showDeprecation> <showWarnings>true</showWarnings> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>${maven-surefire-plugin.version}</version> </plugin> </plugins> </build>
The child Maven module pom.xml using a non-default Java version
The flexy-pool-core-java9
child Maven module that requires a different Java version only needs to override the default jdk.version
Maven property:
<properties> <jdk.version>9</jdk.version> </properties>
And that’s it, we can now build each module using its own minimum viable Java version.
Conclusion
Using multiple Java versions is a common requirement when developing open-source frameworks that target a wide range of project environments. Thanks to the Maven Toolchains plugin, this task is very easy to address.
