Three Approaches to Specify Java Version in Maven and Their Differences

Nov 22, 2025 · Programming · 8 views · 7.8

Keywords: Maven | Java Version Configuration | Compiler Plugin | Multi-module Project | Version Compatibility

Abstract: This article provides an in-depth analysis of three primary methods for specifying Java versions in Maven projects: through properties, Maven compiler plugin configuration, and the release parameter. It systematically examines the implementation principles, applicable scenarios, and mutual differences of each approach, with particular focus on configuration management in multi-module projects, version compatibility issues, and solutions for handling inconsistencies between JAVA_HOME environment variables and POM configurations. Combining Maven official documentation with practical development experience, the article offers comprehensive technical guidance and best practice recommendations for developers.

Fundamental Mechanism of Maven Compiler Plugin

The Maven compiler plugin is a core component in the Maven build process. Even without explicit declaration, Maven automatically binds this plugin to the build lifecycle. By executing the mvn help:effective-pom command, one can observe that the effective POM configuration includes default compiler plugin settings:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <executions>
        <execution>
            <id>default-compile</id>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

This implicit binding mechanism ensures basic compilation functionality, while developers can override default behaviors through explicit configuration.

Analysis of Property-Based Configuration

Using properties to specify Java version is the most concise configuration approach. The Maven compiler plugin has built-in support for specific properties:

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

The advantage of this approach lies in its simplicity and ease of maintenance, particularly suitable for unified management in multi-module projects through parent POM. It's important to note that the notation <java.version>1.8</java.version> is a Spring Boot framework-specific shorthand and is not directly supported in standard Maven projects.

Explicit Plugin Configuration Approach

Specifying Java version through explicit Maven compiler plugin configuration provides finer-grained control:

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

From the implementation mechanism of the Maven compiler plugin, the <source> and <target> elements in plugin configuration actually read the values of maven.compiler.source and maven.compiler.target properties. Therefore, these two configuration approaches are functionally equivalent. The advantage of explicit configuration lies in the ability to configure other compiler parameters simultaneously, such as advanced options like fork and executable.

Modern Approach with Release Parameter

Starting from Maven compiler plugin version 3.6, the release parameter was introduced as a more modern configuration approach:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <release>9</release>
    </configuration>
</plugin>

The corresponding property-based configuration is:

<properties>
    <maven.compiler.release>9</maven.compiler.release>
</properties>

The release parameter is a new compilation option introduced in Java 9 that simultaneously sets the source code version, target platform version, and bootstrap classpath, ensuring better cross-version compilation compatibility. This approach avoids potential API incompatibility issues that may arise with traditional source and target configurations.

Best Practices for Multi-Module Projects

In multi-module Maven projects, it's recommended to use the parent POM's <pluginManagement> for unified compiler configuration management:

<pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</pluginManagement>

Alternatively, use property inheritance:

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

The property-based approach is more concise in multi-module projects, while the plugin configuration approach offers greater flexibility when complex compiler configurations are needed.

Version Compatibility and JAVA_HOME Handling

When the Java version specified in the POM differs from the JDK version pointed to by the JAVA_HOME environment variable, compatibility issues require special attention:

The fundamental principle is: the specified source and target versions cannot be higher than the JDK version pointed to by JAVA_HOME, because older JDKs cannot compile code using newer language features.

When version incompatibility occurs, configure the compiler plugin to use a specific JDK path:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <compilerVersion>1.8</compilerVersion>
        <fork>true</fork>
        <executable>D:\jdk1.8\bin\javac</executable>
    </configuration>
</plugin>

This configuration ensures that even if JAVA_HOME points to a different JDK version, the compilation process still uses the specified JDK version.

Configuration Selection Recommendations

Based on different usage scenarios, the following configuration strategies are recommended:

Regardless of the chosen approach, the key is maintaining consistency and maintainability in project configuration, especially in team collaboration and multi-module projects.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.