Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enforce compilation with a given JDK in Maven

I am working in an enviroment with applications using different Java versions: 7, 8 and later. The developers have thus installed several JDKs and each Maven pom.xml has indeed the correct <source> and <target> tags. However, sometimes the developers unadvertedly compile using a higher JDK. So they may include a Java 8 class like java.time.LocalDate in a Java 7 which will compile because it is able to resolve the import when compiling. But when the application is later moved to run on a JRE 7 it will fail because it is unable to find the Java 8 class. It is possible to create a profile in the pom.xml like:

<profile>
  <id>compiler</id>
    <properties>
      <JAVA_1_4_HOME>C:\Program Files\Java\j2sdk1.4.2_09</JAVA_1_4_HOME>
    </properties>
</profile>

However, the location of the JDK varies per developer and I want a pom.xml which is common for everybody.

So the question is, how to enforce Maven to use a given JDK version? Not only the <source> and <target> but the JDK itself and in a generic way not tied to any given computer.

like image 787
Serg M Ten Avatar asked Jun 19 '20 07:06

Serg M Ten


1 Answers

Initially I've thought that setting source/target to 1.7 for maven-compiler-plugin would be enough to fail the compilation but if you have a JDK 8 installed, the compilation succeeds(strange!).

What you really need is maven-enforcer-plugin. See the below configuration, I've put it to run on validate phase, which is just before compile:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-enforcer-plugin</artifactId>
            <version>3.0.0-M3</version>
            <executions>
                <execution>
                    <id>default-cli</id>
                    <phase>validate</phase>
                    <goals>
                        <goal>enforce</goal>
                    </goals>
                    <configuration>
                        <rules>
                            <requireJavaVersion>
                                <version>[1.7,1.8)</version>
                            </requireJavaVersion>
                        </rules>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Output:

[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ compiler-demo ---
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireJavaVersion failed with message:
Detected JDK Version: 1.8.0-152 is not in the allowed range [1.7,1.8).

You can even set a custom message to make things clearer for your colleagues, e.g.

<rules>
  <requireJavaVersion>
    <version>[1.7,1.8)</version>
    <message>Project requires JDK 7</message>
  </requireJavaVersion>
</rules>

Output:

[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ compiler-demo ---
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireJavaVersion failed with message:
Project requires JDK 7

Just for the sake of exploring the plugin's capabilities, I tried to see if it supports multiple version ranges. It does(running with a JDK 11 to try it out):

<requireJavaVersion>
    <version>[1.7,1.8),[9,10)</version>
</requireJavaVersion>

Output:

[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ compiler-demo ---
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireJavaVersion failed with message:
Detected JDK Version: 11.0.1 is not in the allowed range [1.7,1.8),[9,10).
like image 176
Silviu Burcea Avatar answered Oct 11 '22 10:10

Silviu Burcea