Compiler flags, packaging, code generation and quality checks are all plugin configuration.
Plugins are declared under <build><plugins> with coordinates and a <configuration> block. Maven's plugins (org.apache.maven.plugins group) can omit the groupId. Always pin plugin versions; otherwise Maven warns and picks a possibly outdated default.
Key plugins:
- maven-compiler-plugin:
<release>21</release>,<compilerArgs>,<annotationProcessorPaths>for Lombok or MapStruct. - maven-jar-plugin: manifest entries such as
Main-Class. - maven-shade-plugin or spring-boot-maven-plugin: build a runnable fat jar.
- maven-enforcer-plugin: require a Maven/JDK version, ban duplicate or snapshot dependencies.
- maven-resources-plugin with
<filtering>true</filtering>substitutes${project.version}in resource files. - exec-maven-plugin, build-helper-maven-plugin, jacoco-maven-plugin, spotless-maven-plugin.
An <execution> binds goals to a phase, with its own <id> and configuration; the same plugin can have several executions. Omit <phase> when the goal has a default phase. Run a single execution directly with mvn plugin:goal@executionId.
<pluginManagement> works like dependencyManagement: it fixes versions and configuration for plugins without activating them, so child modules just name the plugin. Put it in the parent POM.
Configuration values can reference properties (${java.version}) and be overridden from the command line with -Dproperty=value only when the plugin exposes a user property (documented per goal, e.g. -Dmaven.compiler.release=17).
Example
<build>
<pluginManagement> <!-- versions/config for the whole build -->
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>21</release>
<compilerArgs><arg>-Xlint:all</arg></compilerArgs>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>enforce-versions</id>
<goals><goal>enforce</goal></goals> <!-- default phase: validate -->
<configuration>
<rules>
<requireMavenVersion><version>[3.9,)</version></requireMavenVersion>
<requireJavaVersion><version>[21,)</version></requireJavaVersion>
<banDuplicatePomDependencyVersions/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>Remember
- Pin plugin versions under build/plugins or pluginManagement
- executions bind goals to phases with their own configuration
- pluginManagement shares settings without activating plugins
- Compiler, surefire, jar/shade and enforcer are the core set
Watch out for
- Leaving plugin versions unspecified, so builds change behavior when Maven's defaults change.