Maven builds a project by executing plugin goals in lifecycle order. A lifecycle contains ordered phases; invoking a phase executes that phase and every earlier phase in the same lifecycle. Plugins contribute goals, and lifecycle bindings select the goals that run for a project packaging.
Project Model and Coordinates #
The POM identifies an artifact by groupId, artifactId, version, and
packaging. Parent POMs, dependency management, and imported BOMs centralize
versions without adding an artifact to the classpath. dependencyManagement
therefore constrains dependencies only after a child declares them.
Inheritance and aggregation are independent. A child inherits from the POM named
by <parent>, while an aggregator lists reactor projects in <modules> and builds
them in dependency order. One POM can perform both roles, but a module need not
inherit from its aggregator. Inspect the merged model and active profiles with:
mvn help:effective-pom
mvn help:active-profilesKeep repositories, credentials, and deployment configuration separate:
- Commit project repositories only when the project requires them.
- Put credentials and organization-specific mirrors in user or CI
settings.xml, not in the POM. - Declare dependency and plugin versions explicitly, either directly or through reviewed management sections. A missing plugin version makes a build depend on Maven’s resolution behavior rather than the source tree.
Lifecycles and Phases #
Maven provides the clean, default, and site lifecycles. Day-to-day builds
use the default lifecycle:
| Phase Range | Purpose |
|---|---|
validate through process-resources | Validate the model, generate inputs, and prepare resources. |
compile through test | Compile production and test code, then execute unit tests. |
package | Create the JAR, WAR, or other distributable artifact. |
pre-integration-test through post-integration-test | Prepare, execute, and dismantle an integration-test environment. |
verify | Run quality checks after tests. |
install | Add the artifact to the local repository. |
deploy | Publish the artifact to a remote repository. |
mvn verify is a suitable CI baseline because it reaches the verification
phase without publishing artifacts. mvn clean verify also removes prior build
outputs. The clean lifecycle has pre-clean, clean, and post-clean;
clean removes generated build files. The site lifecycle generates and can
publish project documentation.
Plugins, Goals, and Executions #
A plugin is build-time code; it is not a project dependency. Configure active
build plugins in build/plugins. Use build/pluginManagement to provide a
version and shared configuration that children or the same POM must explicitly
activate.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>21</release>
</configuration>
</plugin>
</plugins>
</build>An execution binds one or more goals to a phase. Packaging-specific default
bindings provide common goals such as compiling Java source and creating a JAR.
A Mojo’s defaultPhase is used when an execution omits <phase>; it does not
bind an arbitrary third-party goal by itself.
<plugin>
<groupId>org.example</groupId>
<artifactId>example-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<goals><goal>generate</goal></goals>
</execution>
</executions>
</plugin>Invoke a goal directly with a prefix or complete coordinates:
mvn dependency:tree
mvn org.apache.maven.plugins:maven-dependency-plugin:3.7.1:treePrefix resolution can search configured plugin groups and repositories. Complete coordinates are preferable in automation when the POM does not already declare the plugin.
Plugin Internals and Prefix Resolution #
A plugin artifact is identified by <packaging>maven-plugin</packaging>.
Its executable units are mojos, which are implemented as subclasses of
AbstractMojo. The plugin’s own POM can define a <goalPrefix> through
maven-plugin-plugin, and that prefix becomes the short CLI name.
Prefix resolution works in layers:
- if the project already declares a plugin with the requested prefix, Maven can resolve it from the effective POM;
- otherwise Maven checks the built-in
org.apache.maven.pluginsgroup and any extrapluginGroupsdeclared insettings.xml; - if necessary, Maven falls back to artifactId conventions such as
maven-XXX-pluginorXXX-maven-plugin.
That resolution model is why mvn dependency:tree works without a fully
qualified coordinate, while automation often prefers the explicit
groupId:artifactId:version:goal form.
The defaultPhase attribute on @Mojo only supplies a phase for an explicit
execution. It does not create an automatic binding for an unofficial plugin.
Lifecycle bindings come from the packaging model and Maven’s built-in default
bindings, not from the annotation alone.
Dependencies and Scopes #
Maven resolves direct and transitive dependencies into classpaths according to scope:
| Scope | Main Compile | Main Runtime | Test Compile and Runtime |
|---|---|---|---|
compile | yes | yes | yes |
provided | yes | no | yes |
runtime | no | yes | yes |
test | no | no | yes |
Use provided only when the deployment environment supplies a compatible API,
such as a Servlet container. runtime suits drivers and implementations that
the compiler does not need. system requires a local file path and bypasses
normal repository resolution, so it should not be used for reproducible builds.
import applies only to POM dependencies and imports a BOM into dependency
management.
Use mvn dependency:tree to find version mediation and exclusions. Maven’s
nearest-definition rule selects among conflicting transitive versions; equal
depth is resolved by declaration order. A direct declaration or
dependencyManagement entry makes the choice explicit. Exclusions apply only
to the dependency path where they are declared, so prefer management or a BOM
to scattered exclusions.
Repositories, Mirrors, and Settings #
A repository is an artifact source. A mirror is a settings.xml rule that
redirects requests for selected repositories; it does not add dependencies or
replace repository authorization policy.
<mirrors>
<mirror>
<id>company-proxy</id>
<mirrorOf>central</mirrorOf>
<url>https://repository.example.invalid/maven-central</url>
</mirror>
</mirrors>The global settings file is under the Maven installation and the user settings
file is ~/.m2/settings.xml. CI should provide a minimal settings file through
its secret-management mechanism. Do not store repository passwords in a POM.
Maven’s <relocation> metadata lets a publisher redirect an obsolete
coordinate to a replacement coordinate.
Maven Wrapper #
Commit mvnw, mvnw.cmd, and .mvn/wrapper/ so developers and CI use the
declared Maven distribution:
mvn wrapper:wrapper -Dmaven=3.9.9
./mvnw clean verifyReview the distribution URL and checksum when updating the wrapper. The wrapper pins Maven itself; plugin and dependency versions still require POM management.
Comments
Read or comment on GitHub (sign-in required to comment)