Maven is using the wrong version: Explained

In this article we will go through a common issue that you can face when compiling and running applications with Maven. The syntom of this issue is that Maven is using the wrong version during the execution. We will show the cause of the issue and the remediation.

Symptom of Maven using an incorrect version

Firstly, let’s show a proof of concept of this issue. Within your pom.xml you have the following Compiler settings:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

These settings, indicate that Maven will use Java 11 ( if available on your machine) to build the project. As a matter of fact, if you run javap to show the minor and major version of the App.class ( in our project) we get the following output:

javap -verbose target/classes/com/mycompany/app/App.class 

Classfile /home/francesco/tmp/compilertest/target/classes/com/mycompany/app/App.class
  Last modified Jan 30, 2024; size 1093 bytes
  SHA-256 checksum 7f41b748c8ca896c6db6ea5a02785812cb164cd60010f006ac51037895e46048
  Compiled from "App.java"
public class com.mycompany.app.App
  minor version: 0
  major version: 55

The above information indicates that the major version is 55 and the minor version is 0. This corresponds to the Java SE 11 version of the Java programming language. So that’s correct.

On the other hand, let’s verify which Java version Maven uses for execution:

public class App 
{
    public static void main( String[] args )
    {
        String javaVersion = System.getProperty("java.version");

        // Print the Java version
        System.out.println("Java Version: " + javaVersion);
    }
}

To learn how to run a Java Class from Maven check this article: Run a Java Class from Maven made simple

By running “mvn exec:java” we can see that Java 17 was selected for execution:

mvn exec:java
. . .
Java Version: 17.0.10

The solution

Maven uses a checklist of option to choose the Java version for execution:

1. JAVA_HOME environment variable: Maven first looks for the JAVA_HOME environment variable. If this variable is set, Maven uses the JDK installed at this location.

2. Parent POM (Project Object Model): If no JAVA_HOME environment variable is set, Maven looks for a parent POM in the project directory. If a parent POM is found, Maven uses the JAVA_HOME setting specified in the parent POM.

3. Project POM: If no JAVA_HOME environment variable or parent POM is found, Maven looks for the JAVA_HOME setting specified in the project’s POM.

In our case, we have JAVA_HOME which points to Java 17. You can verify it by running “mvn --version“. For example:

To solve the issue, just export the JAVA_HOME variable you want to use for execution:

export JAVA_HOME=/home/user/java/jdk-11.0.21/

Finally, verify that mvn –version outputs the correct java version:

mvn --version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /home/user/apache/apache-maven-3.9.6
Java version: 11.0.21, vendor: Oracle Corporation, runtime: /home/user/java/jdk-11.0.21
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.6.11-200.fc39.x86_64", arch: "amd64", family: "unix"

Finding out JAVA_HOME in Linux

Finally, for Linux users, it can be the case that you are installing OpenJDK with yum/dnf or maybe a Java version is already available on your Machine ( for example with Fedora). To find out the location of your JAVA_HOME you can use the alternatives command as follows:

alternatives --config java

There is 1 program that provides 'java'.

  Selection    Command
-----------------------------------------------
*+ 1           java-17-openjdk.x86_64 (/usr/lib/jvm/java-17-openjdk-17.0.9.0.9-3.fc39.x86_64/bin/java)

The ‘+‘ symbol indicates the manual default, the ‘***‘ indicates the automatic default (the one with the highest number). In this case as there is only one alternative both signs point to the same alternative.

By using the alternatives command you can pick up the right JAVA_HOME and export it to Maven.

Conclusion

This article was a quick walkthough a common issue when compiling and running applications with Maven. We have discussed why the JDK that Maven uses for compilation can differ from the execution JDK and how to fix it