Configuring Maven Compiler Plugin (Java)

Best Practices and Methods For Setting Maven Java Compiler

Table of Contents

1. What is Maven Compiler Plugin

The ‘Maven Compiler Plugin’ or more commonly known as ‘Maven Java Compiler’ is used to compile the source code of your project/application.

Internally this plugin uses the standard ‘javac’ compiler (JDK) and as of version 3.0 of this plugin the default compiler is javax.tools.JavaCompiler

Unlike other Maven plugins, the ‘maven compiler plugin’ is ‘in-built’ and ‘implicit’ in nature. This plugin has two goals, which are already bound to specific phases of the default lifecycle:

  • compile: compile main source files
  • testCompile: compile test source files

As mentioned earlier, the maven compiler plugin is called implicitly and automatically by the maven lifecycle in the appropriate phase. Hence you don´t necessarily need to define it inside ‘pom.xml’ it shall be downloaded and executed automatically by maven as and when required. However, we can certainly define and configure custom behavior and attributes for this plugin by specifying it in the ‘pom.xml’.

2. Default Configuration

As per the default behavior, the ‘maven compiler plugin’ compiles source code compatible with Java 5 (also written as Java 1.5), irrespective of the JDK installed on your machine. However, with custom configuration in your ‘pom.xml’ you can override this behavior and specify your own version of compiler and compatibility version.

Note: The java version used to launch Maven itself (Maven runtime) can be set to a different version than the version used for compiling your source code or project. This can be done using custom configuration in your pom.xml as explained in below examples.

You can find out java version for ‘Maven runtime’ by typing the command ‘mvn -v’ or ‘mvn -version’

3. Common Compilation Error

While starting with Maven projects, it is very common to encounter the below error associated with this plugin. This is nothing but the default behavior as mentioned in the above paragraph and can be rectified by using one of the below mentioned custom configurations for your maven java compiler.

[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] Source option 5 is no longer supported. Use 6 or later.
[ERROR] Target option 1.5 is no longer supported. Use 1.6 or later.
[INFO] 2 errors
[INFO] -------------------------------------------------------------
blank

4. Custom Configuration Java 8 or Earlier

If you are using Java 8 or earlier, you can set the Maven Java Compiler version in your POM file using one of the following three methods:

  • Using POM Properties
  • Using -source and -target values in compiler configuration
  • Using compilerVersion in compiler configuration

Let us start with a standard bare-bone ‘pom.xml’ file and insert our custom configuration for ‘Maven Compiler Plugin’ eventually by three different methods.

<project 
	xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
		http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testoxide</groupId>
  <artifactId>maven-quick-start</artifactId>
  <version>1.0</version>
</project>

4.1. Configure using POM Properties

In this method rather than tweaking the ‘maven compiler’ configuration or ‘build’ configuration’ directly, you can use the POM properties to set the compiler (JDK) versions.

This is the most simple but probably least reliable way. However, which option works best for you depends on the setup of your project and specific requirements i.e. depend on a case by case basis.

<project 
	xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
		http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testoxide</groupId>
  <artifactId>maven-quick-start</artifactId>
  <version>1.0</version>
    <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
</project>

Using the above configuration should give you output classes both compiled and compatible with the specified java (compiler) version which is Java 8 in this case.

4.2. Configure using -source & -target

Another, preferred way for forcing a specific compiler version is by modifying the default parameter values of ‘-source’ and ‘target’ directly in the plugin settings as below.

Here we are setting the JDK/JRE version for both source and target to 1.8

<project 
	xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
		http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testoxide</groupId>
  <artifactId>maven-quick-start</artifactId>
  <version>1.0</version>

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

</project>
NOTE: In some cases, problem with this method is that it does not ‘guarantee’ that the maven compiler would be able to strictly adhere to above settings due to unintended usage of APIs that only exist in JREs which would make your code fail at runtime with a linkage error. For further reference on this read https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html

4.3. Configure using ‘compilerVersion’

You can use this method to compile your code with a ‘very specific’ JDK version, even if it is different than the one used to launch Maven itself. This is probably the most precise of all methods.

Here ‘compilerVersion’ parameter can be used as part of ‘build configuration’ to specify the version of the compiler that the plugin will use. However, you also need to set fork to true for this to work

Using the below ‘POM’ configuration, it is still possible to tell the ‘Maven Compiler Plugin’ the specific JDK to use during compilation. But such configuration will be specific to this plugin, and will not affect others.

<project 
	xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
		http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testoxide</groupId>
  <artifactId>maven-quick-start</artifactId>
  <version>1.0</version>
  
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <verbose>true</verbose>
          <fork>true</fork>
          <executable><!-- path-to-javac --></executable>
          <compilerVersion>1.3</compilerVersion>
        </configuration>
      </plugin>
    </plugins>
  </build>
 
</project>
NOTE: Please note that you need to set the ‘fork’ value to ‘true’ for this method to work. This allows running the compiler in a separate process. If false it uses the built-in compiler, while if true it will use the explicitly mentioned executable. Default value is: false.

4.3.1. Improvise – Use variable for Path

In the above ‘pom.xml’ snippet, rather than hardcoding the path to java compiler, you can replace it with a variable. We can do so by using the following property: <executable>${JAVA_1_4_HOME}/bin/javac</executable>

<project 
	xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
		http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testoxide</groupId>
  <artifactId>maven-quick-start</artifactId>
  <version>1.0</version>
  
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <verbose>true</verbose>
          <fork>true</fork>
          <executable>${JAVA_1_8_HOME}/bin/javac</executable>
          <compilerVersion>1.8</compilerVersion>
        </configuration>
      </plugin>
    </plugins>
  </build>
  
</project>

The best part of using the above property is that different users can specify their own values for this property in their ‘settings.xml’ file, keeping your project portable for different users and machine configurations.

<settings>
  [...]
  <profiles>
    [...]
    <profile>
      <id>compiler</id>
        <properties>
          <JAVA_1_4_HOME>C:\Program Files\Java\j2sdk1.4.2_09</JAVA_1_4_HOME>
        </properties>
    </profile>
  </profiles>
  [...]
  <activeProfiles>
    <activeProfile>compiler</activeProfile>
  </activeProfiles>
</settings>

4.3.2. Improvise – Pass args to compiler

If you wish to pass some arguments to the maven java compiler, you can do so in two ways.

Method 1: Using <configuration> element

You can pass the compiler arguments inside the ‘configuration’ part of the compiler plugin itself. A very common example is to pass min and max memory values as below.

Here we are passing the following arguments related to max and min memory to the compiler:

           <meminitial>128m</meminitial>
           <maxmem>512m</maxmem>

<project 
	xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
		http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testoxide</groupId>
  <artifactId>maven-quick-start</artifactId>
  <version>1.0</version>
  
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <verbose>true</verbose>
          <fork>true</fork>
          <executable>${JAVA_1_8_HOME}/bin/javac</executable>
          <compilerVersion>1.3</compilerVersion>
           <meminitial>128m</meminitial>
           <maxmem>512m</maxmem>
        </configuration>
      </plugin>
    </plugins>
  </build>
  
</project>
NOTE: The fork value needs to be set to true in order for these memory settings to work. Without fork value being true these memory parameters set for compiler will not work.
Method 2: Using explicit <compilerArgs>

You should use ‘<compilerArgs>’ element to pass specific compiler arguments that are not handled by the Compiler Plugin itself but are supported by the compilerId selected. For such arguments, use the Compiler Plugin’s <compilerArgs> parameter.

The following example passes compiler arguments to the javac compiler:

<project 
	xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
		http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testoxide</groupId>
  <artifactId>maven-quick-start</artifactId>
  <version>1.0</version>
  
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <verbose>true</verbose>
          <fork>true</fork>
          <executable>${JAVA_1_8_HOME}/bin/javac</executable>
          <compilerVersion>1.3</compilerVersion>
           <meminitial>128m</meminitial>
           <maxmem>512m</maxmem>
          <compilerArgs>
            <arg>-verbose</arg>
            <arg>-Xlint:all,-options,-path</arg>
           <arg>-Xmaxerrs</arg>
           <arg>1000</arg>
         <arg>-J-Duser.language=en_us</arg>
          </compilerArgs>
        </configuration>
      </plugin>
    </plugins>
  </build>
  
</project>
NOTE: Please note that you need to set the ‘fork’ value to ‘true’ for this method to work. Without fork value being set to true the parameters will not be picked up. Default value is: false.

5. Custom Configuration Java 9 and Beyond

Starting from JDK 9, we can use a new command-line option i.e. ‘-release’ which is accepted by the javac executable and can be used to specify against which Java SE release you want to build the project.

This new argument replaces the traditional ‘source’ and ‘target’ properties used for Java 8 or earlier and will automatically configure the compiler to produce class files compatible with the given platform version which should be Java 9 or above. You can implement this ‘-release’ value in the following two ways :

5.1. Configure using POM Properties

In this method, you can specify the Java compiler version using the ‘maven.compiler.release’ element inside the POM Properties. Here is how the Maven Java compiler release element look inside pom properties:

<project 
   xmlns="http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
      http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testoxide</groupId>
  <artifactId>maven-quick-start</artifactId>
  <version>1.0</version>
    <properties>
    <maven.compiler.release>11</maven.compiler.release>
  </properties>
</project>

5.2. Configure using plugin <configuration>

In this method, instead of the source and target properties (as mentioned in section 4.2 above), you need to use the ‘-release‘ property inside the Maven Java compiler plugin’s ‘<configuration>’ element. Given below is the snippet for such implementation:

<project 
   xmlns="http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
      http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testoxide</groupId>
  <artifactId>maven-quick-start</artifactId>
  <version>1.0</version>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <release>11</release>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
NOTE:

The value in the ‘-release’ parameter follows the new version naming scheme adopted since Java 9. As such, the release number does not start with 1.x anymore.

Also note that ‘-release’ parameter is available for maven-compiler-plugin starting 3.6 version

Tushar Sharma
Tushar Sharmahttps://www.automationdojos.com
Hi! This is Tushar, the author of 'Automation Dojos'. A passionate IT professional with a big appetite for learning, I enjoy technical content creation and curation. Hope you are having a good time! Don't forget to subscribe and stay in touch. Wishing you happy learning!

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts

RELATED POSTS

Java Tutorial #4 – Control Statements

Introduction Control statements are used to change the flow of execution based on changes to certain variables in the code. One of the types of...

How To Create Maven Project in Eclipse Without Archetype

Maven is a very popular build and dependency management tool. Eclipse is an IDE that helps developers write and run Java code easily. In...

How To Convert String To Date in Java

Introduction There are often scenarios in programming, where you will need to convert a date in String format to an actual Date object. For example,...

Format Decimal Numbers using Strings Within Pattern

As mentioned in earlier posts, the java.text.DecimalFormat class is used to format decimal numbers via predefined patterns specified as String. Apart from the decimal separator,...

Convert String to java.time.LocalDate with Formatter

The LocalDate class has an overloaded parse() method. In addition to the String Date, it accepts a DateTimeFormatter instance that specifies the format of...
- Advertisement -spot_img

RECENT 'HOW-TO'

How To Install Oh-My-Posh On Windows PowerShell

Oh-My-Posh is a powerful custom prompt engine for any shell that has the ability to adjust the prompt string with a function or variable. It does not...

Â

MORE ON CODEX

RECENT PROJECTS

Windows JDK Manager (win-jdk-Manager)

ADjo LABS PROJECT : Simple and lightweight desktop utility with Interactive cmd Interface for easy view, re-point and switching between JAVA versions on windows. Demonstrating the capability...

MORE IN THIS CATEGORY

Maven CLI Options and Switches Reference

Maven offers a good set of commands and CLI Options to carry out wide range of Dev tasks. Most of these commands are in...

How To Convert String To Date in Java

Introduction There are often scenarios in programming, where you will need to convert a date in String format to an actual Date object. For example,...

Remove Duplicates from List Using Set.addAll

The Set interface has a method called addAll. This accepts a 'Collection' as the parameter. So if you invoke this method by passing the...

Does VBScript Supports all COM Objects ?

Well the answer in one line is - No VBScript does not supports all COM Objects or Servers! VBScript works with only a subset of ‘Objects’...

Convert List to Array Using For-Loop

The simplest way to convert a List to an array is to use a for-loop. The following code snippet demonstrates this method. First, the code...

CHECKOUT TUTORIALS

Finding Web Elements with Selenium

I'm going to explain in this tutorial about the usage of the findElement and findElements method of Selenium Webdriver on the Chrome web browser....
- Advertisement -spot_img