Maven Plugins: Declaration, Configuration, Executions and Common Plugins
A project never mentions the Java version in pom.xml, and its code contains public record Order(String id, int total) {}. JDK 25 is installed, yet mvn compile fails: Order.java:[3,8] records are not supported in -source 8 (use -source 16 or higher to enable records). The compiling is done not by Maven itself but by maven-compiler-plugin, and when the plugin is not configured, it falls back to its own defaults. In recent Maven 3.9.x releases that is plugin version 3.13.0, whose default language level is 8, no matter which JDK is installed.
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 of a plugin is called a goal. Maven on its own can do almost nothing: all the work is done by plugin goals that are either bound to lifecycle phases or invoked from the command line. A plugin is declared and configured in the <build><plugins> section of pom.xml.
Plugins and Goals: How to Run a Maven Plugin
To run a Maven plugin, you name one of its goals: in mvn checkstyle:check, checkstyle is the plugin prefix and check is the goal. A single plugin can have several goals: maven-compiler-plugin has compile and testCompile, maven-pmd-plugin has pmd, cpd, check and cpd-check. The same goal can also be called by the full plugin coordinates.
| Invocation form | Example | Which plugin version is used |
|---|---|---|
prefix:goal | mvn checkstyle:check | From pom.xml or pluginManagement; if it is not there, the default version from Maven or the latest one from the repository |
groupId:artifactId:goal | mvn org.apache.maven.plugins:maven-checkstyle-plugin:check | Same as in the previous row |
groupId:artifactId:version:goal | mvn org.apache.maven.plugins:maven-checkstyle-plugin:3.6.0:check | Exactly the one given, regardless of pom.xml |
Maven resolves a short prefix only within the plugin groups listed in the pluginGroups setting: by default these are org.apache.maven.plugins and org.codehaus.mojo. A prefix of a plugin from another group, such as spotbugs (com.github.spotbugs), works only if the plugin is declared in the project pom.xml. The artifact name is not a prefix, so the form mvn maven-checkstyle-plugin:check found in old articles does not work:
[ERROR] No plugin found for prefix 'maven-checkstyle-plugin' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories A goal called directly runs on its own, without the earlier build steps. How this differs from running a phase, and why mvn jar:jar can produce an empty jar, is explained in the section Maven Goals vs Phases.
Declaring a Plugin in pom.xml
A plugin is declared in pom.xml inside <build><plugins> with a <plugin> element holding the groupId, artifactId and version coordinates (GAV) — plugins are identified by GAV just like dependencies. A declaration lets you pin the plugin version, set its parameters and bind its goals to build phases.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.6.0</version>
</plugin>
</plugins>
</build> If groupId is omitted, org.apache.maven.plugins is assumed, but it is better to write it for readability. 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. The version numbers in this lesson are real, but always check the latest version on Maven Central or on the Available Plugins page. What GAV is and how the <build> section is organized is described in The build Section.
A plugin declaration without <executions> runs nothing by itself: it only pins the version and settings for the cases when the goal is called from the command line or bound to a phase by the standard lifecycle.
Plugin Configuration: configuration and Properties
Plugin parameters are set in the <configuration> element: every nested tag is the name of a goal parameter. Many parameters can also be set through a property in <properties> or from the command line with -D: such a property is called the user property of the parameter (for example, maven.compiler.release or checkstyle.skip).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<configLocation>google_checks.xml</configLocation>
<consoleOutput>true</consoleOutput>
</configuration>
</plugin> If a parameter is set explicitly in <configuration>, a property with the same meaning does not override it; -D works only for parameters that are not set explicitly in pom.xml. The list of parameters and their user properties is printed by maven-help-plugin:
mvn help:describe -Dplugin=compiler -Ddetail Output (fragment):
Name: Apache Maven Compiler Plugin
...
Goal Prefix: compiler
This plugin has 3 goals:
compiler:compile
Description: Compiles application sources.
...
release
User property: maven.compiler.release
The -release argument for the Java compiler, supported since Java9
...
compiler:help
compiler:testCompile Binding Goals to Phases: executions
To make a plugin goal run automatically during the build, you bind it to a lifecycle phase 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.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<!-- plugin-level: used by all executions and by the command line -->
<configLocation>google_checks.xml</configLocation>
<violationSeverity>warning</violationSeverity>
</configuration>
<executions>
<execution>
<id>validate-style</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin> Now mvn package checks the style first. Output for a class indented with 4 spaces (fragment; google_checks.xml expects 2 spaces):
[INFO] --- checkstyle:3.6.0:check (validate-style) @ shop ---
[WARN] /home/user/shop/src/main/java/com/examclouds/shop/App.java:5:5: 'method def modifier' has incorrect indentation level 4, expected level should be 2. [Indentation]
...
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.6.0:check (validate-style) on project shop: You have 3 Checkstyle violations. What you need to know about executions:
- Default phase. Many goals already have a phase set by the plugin author:
checkstyle:check,pmd:checkandspotbugs:checkare bound toverifyby default. In that case<phase>can be omitted and<goals>is enough. If a goal has no default phase and<phase>is not specified, the goal does not run in the build. - Where to put configuration. Settings at the
<plugin>level apply to all executions and to a call from the command line. Settings inside an<execution>apply only to that execution. The commandmvn checkstyle:checkruns with the iddefault-cliand does not see them. - Several executions. You can run the same goal twice with different settings by giving the executions different
idvalues. Two identicalidvalues in one plugin are a POM read error. - Disabling an inherited execution. If an execution comes from a parent POM, a child module disables it by repeating the same
idwith<phase>none</phase>.
Which goals are already bound to phases without any declaration (compiling, testing, packaging) and in what order the goals of one phase run is shown in the section How Plugin Goals Are Bound to Phases.
Common Maven Plugins: Overview Table
Maven plugins fall into two groups. The first group is enabled by default through the lifecycle: clean, resources, compiler, surefire, jar, install, deploy, site. The second group has to be declared in pom.xml explicitly: failsafe, javadoc, checkstyle, shade, gpg and others. Official plugins have the groupId org.apache.maven.plugins; many useful plugins are published by the MojoHaus community (org.codehaus.mojo).
| Plugin | Main goals | What it does | Enabled by default |
|---|---|---|---|
maven-clean-plugin | clean:clean | Deletes the target directory | Yes (the clean lifecycle) |
maven-resources-plugin | resources:resources, resources:testResources | Copies resources to target/classes, filtering ${...} when enabled | Yes |
maven-compiler-plugin | compiler:compile, compiler:testCompile | Compiles the main and test code (details) | Yes |
maven-surefire-plugin | surefire:test | Runs unit tests | Yes |
maven-failsafe-plugin | failsafe:integration-test, failsafe:verify | Runs integration tests (details) | No |
maven-jar-plugin, maven-war-plugin, maven-ear-plugin | jar:jar, war:war, ear:ear | Package a jar, a war web archive or a Jakarta EE enterprise archive (ear), depending on packaging | Yes, by packaging |
maven-install-plugin, maven-deploy-plugin | install:install, deploy:deploy | Copy the artifact into the local repository / publish it to a remote one | Yes |
maven-site-plugin | site:site, site:deploy | Generates an HTML project site with reports from the <reporting> section | Yes (the site lifecycle) |
maven-javadoc-plugin | javadoc:javadoc, javadoc:jar | Generates Javadoc documentation and a jar with it (details) | No |
maven-source-plugin | source:jar-no-fork | Builds a jar with the sources (-sources.jar) | No |
maven-gpg-plugin | gpg:sign | Signs artifacts with a GPG key (.asc files); signatures are mandatory for publishing to Maven Central | No |
maven-shade-plugin | shade:shade | Builds a "fat" jar together with the dependencies | No |
maven-dependency-plugin | dependency:tree, dependency:analyze | Analyzes and copies dependencies (details) | Callable without a declaration |
maven-help-plugin | help:describe, help:effective-pom | Describes plugins and prints the final project model | Callable without a declaration |
versions-maven-plugin (MojoHaus) | versions:display-plugin-updates, versions:display-dependency-updates | Shows available updates of plugins and dependencies | Callable without a declaration |
maven-enforcer-plugin | enforcer:enforce | Stops the build when a rule is violated (Java version, dependency conflicts) | No |
maven-archetype-plugin | archetype:generate | Creates a project from a template (details) | Callable without a declaration |
maven-plugin-plugin | plugin:descriptor | Generates the descriptor when you develop your own plugin (packaging = maven-plugin) | Yes, for maven-plugin |
"Callable without a declaration" means the goal can be run from the command line (mvn dependency:tree), but the plugin is not part of a regular build until it is bound to a phase. The code quality plugins Checkstyle, PMD and SpotBugs are covered below.
maven-compiler-plugin: Java Version and Compiler Options
maven-compiler-plugin compiles the project sources: the compile goal handles the code in src/main/java, the testCompile goal handles the tests. The plugin is enabled by default; you declare it to pin its version and set parameters. The key parameter is release, the Java version the code is compiled for; without it the plugin defaults apply.
The defaults depend on the plugin version: in older 3.x versions source/target defaulted to 1.5–1.7 (on JDK 20+ that is an immediate Source option 7 is no longer supported error), and since 3.11.0 they default to 8. That is exactly why the record project from the start of the lesson does not compile. The minimal fix is a property the plugin reads by itself:
<properties>
<maven.compiler.release>25</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> Why Java 9+ projects use release instead of the source/target pair is shown with an example in the lesson What Is Maven. If an old example suggests <source>1.9</source>, it is outdated twice over: since Java 9, versions are written without the "1." prefix (9, 17, 25), and release should replace the source/target pair.
A full plugin declaration is needed when you have to set more than the Java version, for example compiler arguments or the Lombok annotation processor:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<configuration>
<release>25</release>
<compilerArgs>
<arg>-parameters</arg>
<arg>-Xlint:all</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.40</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin> | Parameter | User property | What it sets | If omitted |
|---|---|---|---|
release | maven.compiler.release | The Java version: language level, bytecode and available JDK API | The default source/target are used (8 in plugin 3.11.0+) |
source, target | maven.compiler.source, maven.compiler.target | The language level and the bytecode version (without restricting the API) | Depends on the plugin version |
encoding | project.build.sourceEncoding (default value) | The source file encoding | The platform encoding and a warning (in Maven 3.9.x) |
compilerArgs | — | Extra javac options: -parameters (method parameter names in bytecode, needed by Spring and Jackson), -Xlint:all | No extra options |
annotationProcessorPaths | — | Annotation processors (Lombok, MapStruct) that run during compilation | Since JDK 23, processors found on the classpath are not run by default |
Which plugin version Maven actually uses is visible in the build output: the line --- compiler:3.13.0:compile (default-compile) @ shop --- contains both the version and the goal. How Lombok is added as a dependency with provided scope is described in the section Maven Dependency Scope.
Executable jar and Javadoc
For a jar to start with java -jar, its manifest must name the main class: this is done by the archive/manifest/mainClass parameter of maven-jar-plugin. Documentation for the code is generated by maven-javadoc-plugin, which is built on the standard javadoc tool.
Main-Class in the manifest: maven-jar-plugin
By default maven-jar-plugin does not record a main class, and java -jar fails with no main manifest attribute. The fix is a plugin setting:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.examclouds.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin> mvn package
java -jar target/hello-maven-1.0-SNAPSHOT.jar Output (for the App class from the quickstart archetype):
Hello World! Such a jar contains only the project classes. If the code uses third-party libraries, the program fails with NoClassDefFoundError on the first access to them: the dependencies have to be either passed on the classpath or bundled into a "fat" jar with maven-shade-plugin (or spring-boot-maven-plugin in a Spring Boot project).
maven-javadoc-plugin
The plugin generates HTML documentation from /** ... */ comments using the javadoc tool:
mvn javadoc:javadoc Where the result goes depends on how it is run: as part of the site (mvn site) it goes to target/site/apidocs, and when the goal is called directly with plugin versions 3.x it goes to target/reports/apidocs. javadoc prints the exact path in the output. The javadoc:jar goal builds a -javadoc.jar, which, together with a -sources.jar and maven-gpg-plugin signatures, is required to publish a library to Maven Central. Since JDK 8, javadoc checks comments strictly (doclint) and stops on errors such as an unknown tag; you can relax the check temporarily with <doclint>none</doclint>, but fixing the comments is the better option.
Code Quality Checks: Checkstyle, PMD, SpotBugs
Three Maven plugins are used for automatic code quality checks: maven-checkstyle-plugin checks the formatting style of the sources, maven-pmd-plugin looks for suspicious constructs and duplicated code, and spotbugs-maven-plugin analyzes bytecode for likely bugs. Each has a report goal and a check goal that stops the build when violations are found.
| Plugin | What it analyzes | Report | Fails the build | Example finding |
|---|---|---|---|---|
maven-checkstyle-plugin | Sources: formatting and conventions | checkstyle:checkstyle | checkstyle:check | Indentation, line length, missing Javadoc, "magic numbers" |
maven-pmd-plugin | Sources: suspicious constructs; CPD — duplicates | pmd:pmd, pmd:cpd | pmd:check, pmd:cpd-check | An empty catch block, an unused variable, a copy-pasted method |
spotbugs-maven-plugin | Bytecode: bug patterns | spotbugs:spotbugs, spotbugs:gui | spotbugs:check | A possible NullPointerException, equals without hashCode, an unclosed stream |
The check goals of all three plugins are bound to the verify phase by default: add them to <executions> without a <phase>, and mvn verify on CI fails whenever violations appear.
maven-checkstyle-plugin and suppressions
Without configuration, the plugin checks code against the Sun rules (sun_checks.xml); the second built-in rule set is google_checks.xml. The violation report is written to target/checkstyle-result.xml.
mvn checkstyle:check Ready-made rule sets rarely fit a project as a whole, so teams usually use their own rules file or switch off individual checks with a suppressions file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<suppressionsLocation>checkstyle-suppressions.xml</suppressionsLocation>
</configuration>
</plugin> The checkstyle-suppressions.xml file in the project root:
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<!-- everywhere -->
<suppress checks="MagicNumber" files="."/>
<suppress checks="FinalParameters|HiddenField" files="."/>
<!-- only in tests -->
<suppress checks="Javadoc.*" files="[\\/]src[\\/]test[\\/]"/>
<!-- one generated class -->
<suppress checks=".*" files="[\\/]generated[\\/].*\.java"/>
</suppressions> The checks and files attributes are regular expressions: the first is matched against the check name, the second against the file path. The expression [\\/] matches both a forward slash and a backslash, so the rule works on Linux and Windows alike.
The embedded Checkstyle version. Plugin 3.6.0 uses Checkstyle 9.3 by default, which does not know the syntax of the latest Java versions and may fail to parse such files. You upgrade Checkstyle itself with a dependency inside the plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.6.0</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<!-- check the latest version on Maven Central -->
<version>10.21.4</version>
</dependency>
</dependencies>
</plugin> This is an example of a general technique: <dependencies> inside <plugin> change the classpath of the plugin itself and never reach the application classpath.
Subtle point: google_checks and a green build
By default the checkstyle:check goal fails the build only on violations of error severity (the violationSeverity parameter). In google_checks.xml every rule has warning severity, so after switching to it mvn verify prints hundreds of [WARN] lines and still ends with BUILD SUCCESS. To make the check actually stop the build, set <violationSeverity>warning</violationSeverity>, as in the example in the executions section.
maven-pmd-plugin
PMD looks for "bad code" in the sources: unused variables and imports, empty catch blocks, overly complex methods. Its bundled Copy/Paste Detector (CPD) finds duplicated code. The plugin works in two modes.
Reports. Useful when you first add PMD to an existing project that has never used such tools: you can assess the scale of the problems without breaking the build.
mvn pmd:pmd
mvn pmd:cpd Checks. If a violation is found, the build stops. The check and cpd-check goals run the analysis themselves before checking:
mvn pmd:check
mvn pmd:cpd-check A declaration in pom.xml that checks the code on mvn verify:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.26.0</version>
<configuration>
<!-- CPD: minimum duplicate size in tokens -->
<minimumTokens>100</minimumTokens>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
<goal>cpd-check</goal>
</goals>
</execution>
</executions>
</plugin> spotbugs-maven-plugin instead of findbugs-maven-plugin
SpotBugs searches compiled classes for patterns of typical bugs: a possible null dereference, API misuse, concurrency errors. It is the successor of FindBugs: the last FindBugs release (3.0.1) came out in 2015 and does not understand bytecode newer than Java 8, so the findbugs-maven-plugin from old articles is not used on modern JDKs.
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<!-- first three numbers = SpotBugs version -->
<version>4.9.3.0</version>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
</configuration>
</plugin> mvn compile spotbugs:check
mvn spotbugs:gui SpotBugs analyzes bytecode, not sources, so a command-line call needs compilation before the goal (mvn compile spotbugs:check); when the goal is bound to verify, the classes are already compiled. The spotbugs:gui goal opens the findings in a window linked to the source lines. The list of bug patterns is in the SpotBugs documentation.
Maven Plugin Versions and pluginManagement
A plugin version is pinned in pom.xml: in the <plugin> element or centrally in <build><pluginManagement>. If the version is not specified, the installed Maven supplies it for the standard plugins, so the same build on Maven 3.9.0 and 3.9.11 runs with different plugins. The version actually used is shown by the build log and by mvn help:effective-pom.
How to find out a plugin version
| Method | What it shows |
|---|---|
Log lines --- prefix:version:goal (execution-id) @ project --- | Which version actually ran in this build |
mvn help:effective-pom | The final versions of all plugins, including the parent and the Super POM |
mvn versions:display-plugin-updates | Newer versions available and plugins without a pinned version |
| The plugin page on Maven Central or maven.apache.org | The latest release and its Maven and Java requirements |
mvn versions:display-plugin-updates Output (fragment; the numbers depend on the project and the date of the run):
[INFO] The following plugin updates are available:
[INFO] maven-checkstyle-plugin ...................... 3.5.0 -> 3.6.0
[INFO] maven-compiler-plugin ...................... 3.13.0 -> 3.14.0 pluginManagement
<pluginManagement> sets plugin versions and configuration "in case they are used" and does not run any plugin by itself. It usually lives in a parent POM, while modules list the plugin in <plugins> without a version:
<!-- parent pom.xml -->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<configLocation>google_checks.xml</configLocation>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<!-- module pom.xml: version and configuration come from the parent -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
</build> How a parent POM and the effective POM work is described in the section parent, Super POM and Effective POM.
Nuance: pluginManagement does not treat all plugins alike
If maven-checkstyle-plugin with executions is declared only in pluginManagement, the style check never runs, and the build passes silently. Yet the version and settings of maven-compiler-plugin or maven-surefire-plugin from pluginManagement do apply without a declaration in <plugins>: these plugins are already used by the standard lifecycle bindings. The rule is simple: a plugin that is not in the standard bindings must also be listed in <plugins>.
Plugin Setup Slip-ups and How to Fix Them
Most Maven plugin mistakes do not fail the build: the plugin simply does not run or runs with different settings than you expect. The table shows what was done, what happens and how to fix it.
| What was done | What happens | How to fix it |
|---|---|---|
| No Java version set for the compiler | The plugin compiles with source 8 (or 1.5–1.7 in older versions): records are not supported in -source 8 or Source option 7 is no longer supported | The maven.compiler.release property |
mvn maven-checkstyle-plugin:check | No plugin found for prefix 'maven-checkstyle-plugin' | mvn checkstyle:check or the full groupId:artifactId:goal coordinates |
A plugin with executions declared only in pluginManagement | The plugin does not run, the build passes | List the plugin in <build><plugins> |
Settings put inside <execution>, and the goal is run from the command line | The goal runs with the id default-cli and the default settings | Move <configuration> to the <plugin> level |
A plugin without <version> | Warning 'build.plugins.plugin.version' ... is missing; the version depends on the installed Maven | Set the version in <plugin> or in pluginManagement |
google_checks.xml without violationSeverity | checkstyle:check prints warnings and ends with BUILD SUCCESS | <violationSeverity>warning</violationSeverity> |
| New Java syntax with the default Checkstyle | The Checkstyle 9.3 embedded in the plugin cannot parse the file | Add a recent com.puppycrawl.tools:checkstyle dependency to the plugin |
findbugs-maven-plugin in a Java 9+ project | FindBugs does not support bytecode newer than Java 8 | Replace it with com.github.spotbugs:spotbugs-maven-plugin |
Frequently Asked Questions
What is the difference between a plugin and a dependency in Maven?
A dependency (<dependencies>) is a library used by the application code: it goes to the compile, test or runtime classpath. A plugin (<build><plugins>) is a tool of the build itself: it runs inside Maven and never ends up in the application. If a plugin needs an extra library, you list it in <dependencies> inside <plugin>, as in the example with the Checkstyle version.
How do I skip a plugin temporarily during a build?
Most plugins have a skip parameter with its own property: mvn verify -Dcheckstyle.skip -Dpmd.skip -Dspotbugs.skip, and -DskipTests for tests. To disable an execution inherited from a parent, a module repeats its id with <phase>none</phase>. The property name for a specific plugin is shown by mvn help:describe -Dplugin=... -Ddetail.
How do I write my own Maven plugin?
Create a project with packaging = maven-plugin and the dependencies maven-plugin-api and maven-plugin-annotations (scope provided). Each goal is a class that extends AbstractMojo, carries the @Mojo(name = "...") annotation and implements execute(). The plugin descriptor is generated during the build by maven-plugin-plugin. After mvn install the goal can be called from another project by its coordinates. You rarely need your own plugin: check the ready-made ones on maven.apache.org and MojoHaus first.
Where does Maven store downloaded plugins?
In the same place as dependencies: the local repository ~/.m2/repository, under a path built from the groupId, for example org/apache/maven/plugins/maven-compiler-plugin/3.14.0/. Plugins are downloaded from plugin repositories (Maven Central by default) the first time they are used, which is why the first build of a project takes longer. Local and remote repositories are covered in a separate lesson of this module on Maven repositories.
Comments