Building

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 into MyClass.class, and then renamed MyNewClass.java. In this scenario, mvn clean allows eliminating the file MyClass.class from the target 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 present
  • compile: compiles the source code of the project
  • test-compile: compiles the source code of the unit tests of the project
  • test: runs the unit tests
  • package: 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 with this example, 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.11.2</version>
  <configuration>
    <source>21</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.