Maven Plugins: Declaration, Configuration, Executions and Common Plugins - Quiz

Total: 6 questions

1. 

What is a Maven plugin and a plugin goal, and how do you run a goal from the command line?

A Maven plugin is an artifact that provides a set of actions Maven performs during a build: compiling, running tests, packaging a jar, checking code style, generating documentation. Each action is called a goal: maven-compiler-plugin has compile and testCompile, maven-pmd-plugin has pmd, cpd, check, cpd-check. Maven on its own can do almost nothing: all the work is done by goals bound to phases or invoked from the command line.

Three invocation forms:

  • mvn checkstyle:check - prefix and goal; the version comes from pom.xml or pluginManagement, otherwise the default version from Maven or the latest one from the repository;
  • mvn org.apache.maven.plugins:maven-checkstyle-plugin:check - full coordinates, the version is chosen the same way;
  • mvn org.apache.maven.plugins:maven-checkstyle-plugin:3.6.0:check - exactly the given version, regardless of pom.xml.

A short prefix is resolved only within the groups from pluginGroups (by default org.apache.maven.plugins and org.codehaus.mojo); a prefix of a plugin from another group, such as spotbugs, works only if the plugin is declared in pom.xml. The artifact name is not a prefix: mvn maven-checkstyle-plugin:check gives No plugin found for prefix.

A plugin differs from a dependency: a dependency is a library for the application code and goes on its classpath, while a plugin is a tool of the build itself, runs inside Maven and never ends up in the application.

2. 

How do you declare and configure a plugin in pom.xml, and how do you find out which parameters it has?

A plugin is declared in <build><plugins> with a <plugin> element holding groupId, artifactId and version - just like a dependency. Without groupId, org.apache.maven.plugins is assumed. Always specify the version: without it Maven prints the warning 'build.plugins.plugin.version' ... is missing, and the build depends on the installed Maven version.

A declaration without <executions> runs nothing by itself: it pins the version and settings for a command-line call of a goal or for the standard phase bindings.

Parameters go into <configuration>: every nested tag is the name of a goal parameter, for example <configLocation>google_checks.xml</configLocation>. Many parameters have a user property that can be set in <properties> or with -D (maven.compiler.release, checkstyle.skip). If a parameter is set explicitly in <configuration>, the property does not override it: -D works only for parameters not set explicitly.

The list of parameters and their user properties is printed by mvn help:describe -Dplugin=compiler -Ddetail. If a plugin needs an extra library, it goes into <dependencies> inside <plugin> - this changes the classpath of the plugin itself, not of the application.

3. 

How do you bind a plugin goal to a phase with executions, and what do you need to know about execution settings?

In the <executions> block, each <execution> has a unique <id>, a <phase> and a list of <goals>. Whenever that phase (or any later one) runs, Maven executes the listed goals; the log shows --- checkstyle:3.6.0:check (validate-style) @ shop ---.

  • Default phase. Many goals already have a phase set by the plugin author: checkstyle:check, pmd:check, spotbugs:check are bound to verify, so <phase> can be omitted. If a goal has no default phase and <phase> is not specified, the goal does not run in the build.
  • Where settings go. <configuration> at the <plugin> level applies to all executions and to a command-line call; inside an <execution> it applies only to that execution. mvn checkstyle:check runs with the id default-cli and does not see execution settings.
  • Several executions. The same goal can run twice with different settings if the executions have different id values; two identical id values in one plugin are a POM read error.
  • Disabling an inherited execution. A module disables an execution from the parent POM by repeating the same id with <phase>none</phase>.

To skip a plugin temporarily, use its skip parameter: mvn verify -Dcheckstyle.skip -Dpmd.skip -Dspotbugs.skip; the property name is shown by mvn help:describe -Dplugin=... -Ddetail.

4. 

Which Maven plugins are enabled by default, which must be declared, and how do you get an executable jar and Javadoc with plugins?

Enabled by default through the lifecycle: clean, resources, compiler, surefire, jar (war, ear - by packaging), install, deploy, site. Must be declared: failsafe, javadoc, source, gpg, shade, enforcer, checkstyle, pmd, spotbugs. Official plugins have the groupId org.apache.maven.plugins; many useful ones are published by the MojoHaus community (org.codehaus.mojo, for example versions-maven-plugin). The dependency, help, versions and archetype plugins are callable without a declaration (mvn dependency:tree), but they are not part of a regular build until a goal is bound to a phase.

Executable jar. By default maven-jar-plugin does not record a main class; you set it with <archive><manifest><mainClass>, and then java -jar works. Such a jar contains only the project classes: third-party libraries need a classpath or a "fat" jar built with maven-shade-plugin.

Javadoc. maven-javadoc-plugin generates HTML documentation from /** ... */ comments: mvn javadoc:javadoc. As part of the site (mvn site) the output goes to target/site/apidocs; when the goal is called directly with plugin versions 3.x, to target/reports/apidocs. javadoc:jar builds a -javadoc.jar; together with a -sources.jar and maven-gpg-plugin signatures it is required for publishing to Maven Central. Since JDK 8, javadoc checks comments strictly (doclint) and stops on errors; <doclint>none</doclint> relaxes the check, but fixing the comments is better.

5. 

How do you configure maven-compiler-plugin: the Java version, encoding, compiler arguments and annotation processors?

maven-compiler-plugin is enabled by default: the compile goal compiles src/main/java, testCompile compiles the tests. You declare it to pin its version and set parameters.

  • release (maven.compiler.release) - the Java version: language level, bytecode and available JDK API. Without it the plugin defaults apply: source/target 1.5-1.7 in older 3.x (an immediate Source option 7 is no longer supported error on JDK 20+), 8 since 3.11.0, which is why a record does not compile even on JDK 25. The minimal fix is the property <maven.compiler.release>25</maven.compiler.release>. Since Java 9, versions are written without the "1." prefix: <source>1.9</source> from old examples is outdated.
  • encoding - defaults to project.build.sourceEncoding; without it Maven 3.9.x uses the platform encoding and prints a warning.
  • compilerArgs - extra javac options: -parameters (method parameter names in bytecode, needed by Spring and Jackson), -Xlint:all.
  • annotationProcessorPaths - annotation processors (Lombok, MapStruct); since JDK 23, processors found on the classpath are not run by default, so you list them here.

The plugin version actually used is visible in the build output: --- compiler:3.13.0:compile (default-compile) @ shop ---.

6. 

How do the Checkstyle, PMD and SpotBugs code quality plugins differ, and how do you add them to the build?

  • maven-checkstyle-plugin checks the formatting style of the sources (indentation, line length, Javadoc, "magic numbers"). Report - checkstyle:checkstyle, failing the build - checkstyle:check. Without configuration the Sun rules apply (sun_checks.xml); the second built-in set is google_checks.xml. Individual checks are switched off with a suppressions file (suppressionsLocation), where checks and files are regular expressions. Plugin 3.6.0 uses Checkstyle 9.3 by default, which cannot parse recent Java syntax; you upgrade it with a com.puppycrawl.tools:checkstyle dependency inside the plugin.
  • maven-pmd-plugin looks for suspicious constructs in the sources (an empty catch, unused variables), and CPD finds duplicated code. The reports pmd:pmd and pmd:cpd suit a first assessment of a project; pmd:check and pmd:cpd-check fail the build.
  • spotbugs-maven-plugin analyzes bytecode for bug patterns (a possible NullPointerException, equals without hashCode). From the command line it needs compilation first: mvn compile spotbugs:check. It is the successor of FindBugs, which does not understand bytecode newer than Java 8.

The check goals of all three plugins are bound to verify by default: add them to <executions> without a <phase>, and mvn verify on CI fails whenever violations appear.

Versions of these and other plugins are pinned in <plugin> or centrally in pluginManagement; the version actually used is shown by the build log and mvn help:effective-pom, available updates by mvn versions:display-plugin-updates.

Page 1 of 1