Maven - maven-compiler-plugin

The maven-compiler-plugin plugin is used to compile the source code of a Maven project. This plugin has two goals, which are already bound to specific phases of the default lifecycle:

  1. compile – compile main source files
  2. testCompile – compile test source files

https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin

Configuration

By default, the compiler plugin compiles source code compatible with Java 5, and the generated classes also work with Java 5 regardless of the JDK in use. We can modify these settings in the configuration element:

According to the Maven documentation of the compiler plugin, the <source> and the <target> elements in the compiler configuration use the properties maven.compiler.source and maven.compiler.target if they are defined.

https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html

jdk8

Until Java 8, we used the version number as 1.x where x represents Java’s version, like 1.8 for Java 8.

https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html

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

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>${mvn.compiler.source}</source>
                <target>${mvn.compiler.target}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

Java 9 and Beyond

For Java 9 and above, we can just use the version number directly. So, for java17, we just say 17.

release option

https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-release.html

Starting from the JDK 9 version, we can use a new -release command-line option. This new argument will automatically configure the compiler to produce class files that will link against the implementation of the given platform version.

By default, the -source and -target options don’t guarantee a cross-compilation. This means that we cannot run our application on older versions of the platform. To cross-compile correctly, the new -release option replaces three flags: -source, -target and -bootclasspath.

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

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.12.1</version>
    <configuration>
        <release>${mvn.compiler.release}</release>
    </configuration>
</plugin>

java17 with other settings

<properties>
    <mvn.compiler.release>17</maven.compiler.release>
    <mvn.compiler.source>17</mvn.compiler.source>
    <mvn.compiler.target>17</mvn.compiler.target>
</properties>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.6.2</version>
  <configuration>
    <source>${mvn.compiler.source}</source>
    <target>${mvn.compiler.target}</target>
    <release>${mvn.compiler.release}</release>
    <annotationProcessorPaths>
      <path>
         <groupId>org.mapstruct</groupId>
         <artifactId>mapstruct-processor</artifactId>
         <version{mapstruct.version}</version> <!-- 1.5.5.FINAL or higher for java 17 -->
       </path>
       <path>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <version>{lombok.version}</version> <!-- 1.8.22 or higher for java 17 -->
       </path>
       <path>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok-mapstruct-binding</artifactId>
         <version>0.2.0</version>
       </path>
    </annotationProcessorPaths>
    <compilerArgs>
        <arg>-Amapstruct.defaultComponentModel=spring</arg>
    </compilerArgs>
 </configuration>
</plugin>

compilerArgs

https://maven.apache.org/plugins/maven-compiler-plugin/examples/pass-compiler-arguments.html

Sometimes we want to pass arguments to the javac compiler. This is where the compilerArgs parameter comes in handy.

For instance, we can specify the following configuration for the compiler to warn about unchecked operations:

<configuration>
    <!-- other configuration -->
    <compilerArgs>
        <arg>-Xlint:unchecked</arg>
    </compilerArgs>
</configuration>

When compiling this class:

public class Data {
    List<String> textList = new ArrayList();

    public void addText(String text) {
        textList.add(text);
    }

    public List getTextList() {
        return this.textList;
    }
}

we’ll see an unchecked warning on the console:

[WARNING] ... Data.java:[7,29] unchecked conversion
  required: java.util.List<java.lang.String>
  found:    java.util.ArrayList

What is the purpose of <java.version>

<properties>
    <java.version>17</java.version>
</properties>

<java.version> is not referenced in the Maven documentation. It is specific to Spring Boot. It allows to set the source and the target java version with the same version such as this one to specify java 1.8 for both.

References

  1. https://www.baeldung.com/maven-compiler-plugin
  2. https://www.baeldung.com/maven-java-version