Overview of Common Maven Plugins

In the Maven ecosystem, the build lifecycle itself is remarkably lean, defining only abstract phases such as validate, compile, test, package, and others. What truly empowers Maven to handle concrete tasks—compilation, packaging, testing, deployment, and beyond—is the extensive plugin architecture operating behind the scenes.

Maven plugins primarily fall into two categories: build plugins, which execute during the build process and are configured within the <build> section of pom.xml, and reporting plugins, which run at the site generation stage and are configured under <reporting>. This article surveys the most frequently used and critical Maven plugins in daily Java development, along with their essential configuration patterns.

Build Plugins

These plugins form the core of any Maven-driven Java project, transforming source code into distributable artifacts.

Maven Compiler Plugin (maven-compiler-plugin)

The compiler plugin is responsible for translating Java source files into bytecode. With frequent JDK version upgrades, explicitly declaring the source and target versions is essential to ensure consistent compilation behavior across environments.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.11.0</version>
            <configuration>
                <source>17</source>
                <target>17</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

Maven JAR Plugin (maven-jar-plugin)

This plugin packages compiled class files into a standard JAR archive. To produce an executable JAR that includes a Main-Class manifest entry, the archive element can be configured to set the manifest attributes.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.3.0</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>com.example.App</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

Spring Boot Maven Plugin (spring-boot-maven-plugin)

In Spring Boot microservice projects, this plugin is indispensable. It packages the application as a "Fat JAR" containing all runtime dependencies and provides the repackage goal, enabling direct execution via java -jar.

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>3.1.5</version>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Testing and Code Quality Plugins

Ensuring code reliability and maintainability relies heavily on automated testing and static analysis. Maven offers mature plugins to support these workflows.

Maven Surefire Plugin (maven-surefire-plugin)

The Surefire plugin executes unit tests during the test phase, supporting frameworks such as JUnit and TestNG. In large projects, tests can be globally skipped via the -Dmaven.test.skip=true command-line flag, or configured per-plugin to control which test classes run.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.2.1</version>
    <configuration>
        <!-- Exclude specific test classes -->
        <exclude>${skipTests}</exclude>
    </configuration>
</plugin>

JaCoCo Maven Plugin (jacoco-maven-plugin)

JaCoCo instruments code and generates coverage reports during the build. By binding the prepare-agent goal before test execution and report afterward, teams can quantify test coverage and identify untested code paths.

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Auxiliary and Operational Plugins

Beyond core build and test functionality, several plugins assist with project maintenance, dependency management, and artifact publishing.

Maven Source Plugin (maven-source-plugin)

This plugin attaches a sources JAR (-sources.jar) to the build output. It is particularly valuable when publishing libraries to internal repositories or Maven Central, as it enables other developers to inspect source code and debug effectively.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>3.3.0</version>
    <executions>
        <execution>
            <id>attach-sources</id>
            <goals>
                <goal>jar-no-fork</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Maven Resources Plugin (maven-resources-plugin)

Resources such as configuration files under src/main/resources are processed by this plugin. It supports variable filtering, allowing placeholders in property files to be replaced with actual values during the build.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.3.1</version>
    <configuration>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>

Versions Maven Plugin (versions-maven-plugin)

A pragmatic tool for tracking and upgrading dependency versions. It provides goals to display available updates for project dependencies or plugins, and can batch-update version numbers across multi-module projects.

Common command-line operations:

  • Check for dependency updates: mvn versions:display-dependency-updates
  • Check for plugin updates: mvn versions:display-plugin-updates

Best Practices When Working with Maven Plugins

To maintain build consistency and avoid configuration drift, consider the following guidelines:

  1. Pin plugin versions explicitly: Avoid using RELEASE or LATEST as version identifiers. Specify exact versions (e.g., 3.11.0) to ensure reproducible builds across different machines and CI environments.
  2. Leverage <pluginManagement> in parent POMs: Centralize plugin version definitions and default configurations in a parent project’s <pluginManagement> section. Child modules then only need to declare the plugin name, reducing redundancy and ensuring version alignment.
  3. Understand lifecycle binding: Many plugin goals are default-bound to specific Maven lifecycle phases. If the expected behavior isn’t observed, consult the official documentation or invoke a phase directly via mvn <phase> to trigger the intended goal.

By thoughtfully selecting and configuring these plugins, Maven becomes a highly adaptable orchestration layer for Java project automation, from compilation to deployment and beyond.