Get up to speed with the core of Maven quickly, and then go beyond the foundations into the more powerful functionality of the build tool, such as profiles, scopes, multi-module projects and quite a bit more:
Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.
Get started with mocking and improve your application tests using our Mockito guide:
Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.
Get started with understanding multi-threaded applications with our Java Concurrency guide:
Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:
Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.
But these can also be overused and fall into some common pitfalls.
To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:
Get started with Spring and Spring Boot, through the Learn Spring course:
>> LEARN SPRINGExplore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:
Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.
I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.
You can explore the course here:
Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.
Get started with Spring Data JPA through the guided reference course:
Refactor Java code safely β and automatically β with OpenRewrite.
Refactoring big codebases by hand is slow, risky, and easy to put off. Thatβs where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.
Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions β one for newcomers and one for experienced users. Youβll see how recipes work, how to apply them across projects, and how to modernize code with confidence.
Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.
β’ The Maven Failsafe Plugin
β’ Quick Guide to the Maven Surefire Plugin
β’ The Maven Deploy Plugin
β’ The Maven Clean Plugin
β’ The Maven Verifier Plugin
β’ The Maven Site Plugin
β’ Guide to the Core Maven Plugins
1. Overview
This quick tutorial introduces the compiler plugin, one of the core plugins of the Maven build tool.
For an overview of the other core plugins, refer to this article.
2. Plugin Goals
The compiler 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:
- compile β compile main source files
- testCompile β compile test source files
Hereβs the compiler plugin in the POM:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
...
</configuration>
</plugin>
We can find the latest version of this plugin here.
3. 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:
<configuration>
<source>1.8</source>
<target>1.8</target>
<-- other customizations -->
</configuration>
For convenience, we can set the Java version as properties of the POM:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
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
As both goals of the compiler plugin are automatically bound to phases in the Maven default lifecycle, we can execute these goals with the commands mvn compile and mvn test-compile.
4. Java 9 Updates
4.1. Configuration
Until Java 8, we used the version number as 1.x where x represents Javaβs version, like 1.8 for Java 8.
For Java 9 and above, we can just use the version number directly:
<configuration>
<source>9</source>
<target>9</target>
</configuration>
Similarly, we can define the version using properties as:
<properties>
<maven.compiler.source>9</maven.compiler.source>
<maven.compiler.target>9</maven.compiler.target>
</properties>
Maven added its support for Java 9 in 3.5.0, so weβll need at least that version. Weβll also need at least 3.8.0 of the maven-compiler-plugin:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
4.2. Build
Now itβs time to test our configuration.
First, letβs create a MavenCompilerPlugin class in which weβre importing a package from another module.
A simple one is javax.xml.XMLConstants.XML_NS_PREFIX:
public class MavenCompilerPlugin {
public static void main(String[] args) {
System.out.println("The XML namespace prefix is: "
+ XML_NS_PREFIX);
}
}
Next, letβs compile it:
mvn -q clean compile exec:java
-Dexec.mainClass="com.baeldung.maven.java9.MavenCompilerPlugin"
When using Java 9 defaults, though, weβll get an error:
[ERROR] COMPILATION ERROR :
[ERROR] .../MavenCompilerPlugin.java:[3,20]
package javax.xml is not visible
(package javax.xml is declared in module java.xml,
but module com.baeldung.maven.java9 does not read it)
[ERROR] .../MavenCompilerPlugin.java:[3,1]
static import only from classes and interfaces
[ERROR] .../MavenCompilerPlugin.java:[7,62]
cannot find symbol
symbol: variable XML_NS_PREFIX
location: class com.baeldung.maven.java9.MavenCompilerPlugin
The error comes from the fact that this package is in a separate module that we havenβt included yet in our build.
The simplest way to solve this is by creating a module-info.java class and indicating that we require the java.xml module:
module com.baeldung.maven.java9 {
requires java.xml;
}
Now we can try again:
mvn -q clean compile exec:java
-Dexec.mainClass="com.baeldung.maven.java9.MavenCompilerPlugin"
And our output will be:
The XML namespace prefix is: xml
5. Conclusion
In this article, we went over the compiler plugin and described how to use it. We also learned about Mavenβs support for Java 9.
