Building #
Cleaning #
The command
mvn clean
attempts to delete all content generated during a previous build (in particular, .class
files).
Example. Let us assume that
MyClass.java
is compiled intoMyClass.class
, and then renamedMyNewClass.java
. In this scenario,mvn clean
allows eliminating the fileMyClass.class
from thetarget
directory.
The default lifecycle #
Maven’s default lifecycle is a sequence of 23 operations (called phases) that can be executed during a build.
These include (in order):
validate
: checks if all the information needed for the build is presentcompile
: compiles the source code of the projecttest-compile
: compiles the source code of the unit tests of the projecttest
: runs the unit testspackage
: packages the compiled code in its distributable format (such as a jar)install
: installs the package into the local repository (for use as a dependency in other local projects)
Each phase can be executed via command-line with mvn <phaseName>
.
For instance:
mvn package
Warning. Executing any of these phases triggers the execution of all phases that precede it.
For instance, executing the test
phase triggers the execution of validate
, compile
and test-compile
(among others).
Goals and plugins #
A build phase (like
package
) consists of so-called goals.A goal can be declared, configured and associated to a specific phase via a so-called plugin.
In a POM:
- a plugin is specified within the
<plugin></plugin>
tag, and - plugins are declared within:
<build>
<plugins>
...
</plugins>
</build>
For instance, here is the plugin called maven-jar-plugin
, as it is inherited from the Super POM:
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
This plugin assigns the goal jar
to the phase package
.
Intuitively, this specifies that the phase package
must produce a jar
file (as opposed to other formats like war
or ear
).
In order to make this jar executable (and specify the main class of the application), we can add information to this inherited plugin,
in the pom.xml
file of the project, as follows:
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.example.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
...
</plugins>
</build>
The effective POM in this example contains:
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.example.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
...
</plugins>
</build>
A plugin can contain several goals, and these may or may not be assigned to a specific phase.
Besides, a goal can be executed independently from a phase, with the command:
mvn myplugin:myGoal
For instance, the javafx maven plugin has a goal run
to start a JavaFX application.
It can be executed with:
mvn javafx:run
Installing a plugin #
Maven plugins are available for a variety of tasks, like code analysis, Javadoc generation, parser generation, etc.
A plugin is a Maven artifact. Similarly to a dependency, an external plugin can be downloaded from Maven Central and installed into the local repository , as follows:
<build>
<plugins>
...
<plugin>
<groupId> XXX </groupId>
<artifactId> XXX </artifactId>
<version> XXX </version>
...
</plugin>
...
</plugins>
</build>
However, as illustrated above, additional XML attributes may be needed to configure the plugin. These are often specific to a plugin.
Useful plugins #
The assembly plugin #
The assembly plugin allows building a über jar (i.e. including dependencies), as opposed to the maven-jar-plugin
, which can build a thin jar.
This is a simple way to distribute an end-user application (as opposed to a library).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.7.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>org.example.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
<descriptorRef>src</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
In this example, the execution of the goal (called single
) is attached to the phase package
, so the über jar can be produced like a regular jar, with:
mvn package
The source plugin #
The source plugin can package source code as a jar. This allows:
- distributing a Java library alongside its source code, and/or
- installing the library in the local repository together with the source (and navigate through it with an IDE).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
In this example, the execution of the goal (called jar-no-fork
) is attached to the phase verify
.
The Javadoc plugin #
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.3</version>
<configuration>
<source>17</source>
</configuration>
</plugin>
This plugin has many goals, which are often executed independently (i.s. not bound to a phase).
For instance:
mvn javadoc:javadoc
generates Javadoc for the project in the folder target/site
.