Maven Compiler Plugin
last modified June 9, 2025
In this article we show how to configure Java compilation using the
Maven Compiler Plugin
. This plugin controls how Maven compiles
your Java source code.
The Maven Compiler Plugin is used to compile the sources of your project. It handles both main source compilation and test source compilation, allowing you to specify different Java versions, compiler arguments, and other compilation settings.
Basic Configuration
Let's start with a basic example that demonstrates how to configure the Compiler plugin with specific Java versions and encoding settings.
<?xml version="1.0" encoding="UTF-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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>compiler-example</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.12.1</version> <configuration> <source>17</source> <target>17</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
This basic configuration sets up Java 17 compilation with UTF-8 encoding. The plugin will compile both your main sources and test sources using these settings.
<source>17</source> <target>17</target>
Specifies the Java version for source code compatibility and target bytecode version. Source defines what Java language features can be used, while target defines the minimum JVM version required to run the compiled code.
<encoding>UTF-8</encoding>
Sets the character encoding for source files. This ensures consistent compilation across different platforms and environments.
Sample Application
Let's create a simple application that uses modern Java features to demonstrate the compiler configuration:
package com.example; import java.util.List; import java.util.stream.Collectors; public class ModernJavaApp { public static void main(String[] args) { System.out.println("Maven Compiler Plugin Example"); // Using modern Java features (Java 8+) var numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); var evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .map(n -> "Number: " + n) .collect(Collectors.toList()); System.out.println("Even numbers:"); evenNumbers.forEach(System.out::println); // Using text blocks (Java 15+) var jsonTemplate = """ { "name": "Maven Compiler Example", "version": "1.0.0", "features": ["compilation", "java17", "modern-syntax"] } """; System.out.println("JSON Template:"); System.out.println(jsonTemplate); } }
Building the Project
To compile the project, run the following Maven command:
$ mvn clean compile
This compiles your main sources using the configured Java version and settings. You can also run the application:
$ mvn exec:java -Dexec.mainClass="com.example.ModernJavaApp" Maven Compiler Plugin Example Even numbers: Number: 2 Number: 4 Number: 6 Number: 8 Number: 10 JSON Template: { "name": "Maven Compiler Example", "version": "1.0.0", "features": ["compilation", "java17", "modern-syntax"] }
Advanced Compiler Options
The Compiler plugin supports many advanced options for fine-tuning the compilation process. Here's a comprehensive configuration example:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.12.1</version> <configuration> <source>17</source> <target>17</target> <encoding>UTF-8</encoding> <!-- Show deprecation warnings --> <showDeprecation>true</showDeprecation> <!-- Show unchecked warnings --> <showWarnings>true</showWarnings> <!-- Fail on warning --> <failOnWarning>false</failOnWarning> <!-- Verbose compilation output --> <verbose>false</verbose> <!-- Optimize compiled code --> <optimize>true</optimize> <!-- Generate debugging information --> <debug>true</debug> <!-- Include debug symbols --> <debuglevel>lines,vars,source</debuglevel> <!-- Custom compiler arguments --> <compilerArgs> <arg>-Xlint:all</arg> <arg>-Xlint:-processing</arg> <arg>-Werror</arg> </compilerArgs> <!-- Annotation processing --> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> </path> </annotationProcessorPaths> </configuration> </plugin>
This advanced configuration includes several important compiler options:
<showDeprecation>true</showDeprecation> <showWarnings>true</showWarnings>
Enables display of deprecation warnings and general compiler warnings during compilation, helping identify potential issues in your code.
<compilerArgs> <arg>-Xlint:all</arg> <arg>-Xlint:-processing</arg> </compilerArgs>
Passes additional arguments to the Java compiler. This example enables all lint warnings except annotation processing warnings.
<debuglevel>lines,vars,source</debuglevel>
Specifies what debugging information to include in the compiled classes. Useful for debugging and development environments.
Different Configurations for Main and Test Sources
Sometimes you need different compilation settings for main sources and test sources. Here's how to configure separate settings:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.12.1</version> <executions> <execution> <id>default-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> <configuration> <source>17</source> <target>17</target> <encoding>UTF-8</encoding> <showDeprecation>true</showDeprecation> <showWarnings>true</showWarnings> <compilerArgs> <arg>-Xlint:all</arg> <arg>-Werror</arg> </compilerArgs> </configuration> </execution> <execution> <id>default-testCompile</id> <phase>test-compile</phase> <goals> <goal>testCompile</goal> </goals> <configuration> <source>17</source> <target>17</target> <encoding>UTF-8</encoding> <showDeprecation>false</showDeprecation> <showWarnings>false</showWarnings> <compilerArgs> <arg>-Xlint:none</arg> </compilerArgs> </configuration> </execution> </executions> </plugin>
This configuration uses strict compilation settings for main sources (with warnings treated as errors) but more relaxed settings for test sources.
Multi-Release JAR Support
Java 9 introduced Multi-Release JARs that can contain different versions of classes for different Java versions. Here's how to configure this:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.12.1</version> <configuration> <source>11</source> <target>11</target> <encoding>UTF-8</encoding> </configuration> <executions> <execution> <id>compile-java-17</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> <configuration> <release>17</release> <compileSourceRoots> <compileSourceRoot>${project.basedir}/src/main/java17</compileSourceRoot> </compileSourceRoots> <outputDirectory>${project.build.outputDirectory}/META-INF/versions/17</outputDirectory> </configuration> </execution> </executions> </plugin>
This creates a Multi-Release JAR with Java 11 as the base version and Java 17 specific implementations in the appropriate META-INF/versions directory.
package com.example; public class VersionSpecificCode { public static String getJavaVersion() { return "Running on Java " + System.getProperty("java.version"); } public static String getFeatureInfo() { return "Base Java 11 implementation"; } }
package com.example; public class VersionSpecificCode { public static String getJavaVersion() { return "Running on Java " + System.getProperty("java.version"); } public static String getFeatureInfo() { // Using Java 17 specific features var features = """ Java 17 enhanced implementation with: - Text blocks - Pattern matching - Records - Sealed classes """; return features.strip(); } }
Annotation Processor Configuration
The Compiler plugin can be configured to work with annotation processors like Lombok, MapStruct, or custom processors:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.12.1</version> <configuration> <source>17</source> <target>17</target> <encoding>UTF-8</encoding> <!-- Annotation processor configuration --> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> </path> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.5.5.Final</version> </path> </annotationProcessorPaths> <!-- Annotation processor options --> <compilerArgs> <arg>-Amapstruct.defaultComponentModel=spring</arg> <arg>-Amapstruct.unmappedTargetPolicy=ERROR</arg> </compilerArgs> <!-- Generate source files for annotation processors --> <generatedSourcesDirectory>${project.build.directory}/generated-sources/annotations</generatedSourcesDirectory> </configuration> </plugin>
This configuration sets up both Lombok and MapStruct annotation processors with specific options and a custom directory for generated sources.
<annotationProcessorPaths>
Specifies the classpath for annotation processors, allowing them to run during compilation without being included in the project dependencies.
<compilerArgs> <arg>-Amapstruct.defaultComponentModel=spring</arg> </compilerArgs>
Passes specific options to annotation processors using the -A flag followed by the option key and value.
Compiler Plugin Properties
You can also configure the Compiler plugin using Maven properties, which is often more convenient for simple configurations:
<properties> <!-- Java version properties --> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <maven.compiler.release>17</maven.compiler.release> <!-- Encoding --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <!-- Compiler options --> <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation> <maven.compiler.showWarnings>true</maven.compiler.showWarnings> <maven.compiler.optimize>true</maven.compiler.optimize> <maven.compiler.debug>true</maven.compiler.debug> <!-- Plugin version --> <maven.compiler.plugin.version>3.12.1</maven.compiler.plugin.version> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> </plugin> </plugins> </build>
This approach uses Maven properties to configure the Compiler plugin, making it easier to manage and override settings from the command line or parent POMs.
<maven.compiler.release>17</maven.compiler.release>
The release parameter is preferred over separate source and target parameters when using Java 9+, as it ensures full compatibility with the specified version.
Common Compiler Plugin Use Cases
Here are some common scenarios and their configurations:
<!-- For projects that need to maintain Java 8 compatibility --> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <maven.compiler.testSource>17</maven.compiler.testSource> <maven.compiler.testTarget>17</maven.compiler.testTarget> </properties>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.12.1</version> <configuration> <release>17</release> <showDeprecation>true</showDeprecation> <showWarnings>true</showWarnings> <failOnWarning>true</failOnWarning> <compilerArgs> <arg>-Xlint:all</arg> <arg>-Werror</arg> </compilerArgs> </configuration> </plugin>
Source
Maven Compiler Plugin - reference
In this article we have shown how to configure Java compilation using the Maven Compiler Plugin with various options and scenarios.
Author
List all Java tutorials.