CHAPTER 5

image

Maven Life Cycle

Goals and Plug-ins

Build processes generating artifacts typically require several steps and tasks to be completed successfully. Examples of such tasks include compiling source code, running a unit test, and packaging of artifacts. Maven uses the concept of goals to represent such granular tasks.

To better understand what a goal is, let’s look at an example. Listing 5-1 shows the compile goal executed on gswm project code under C:apressgswm-bookchapter5gswm. As the name suggests, the compile goal compiles source code. The compile goal identifies the Java class HelloWorld.java under src/main/java, compiles it, and places the compiled class file under the targetclasses folder.

Listing 5-1. Maven compile Goal

C:apressgswm-bookchapter5gswm>mvn compiler:compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Getting Started with Maven 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-cli) @ gswm ---
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[INFO] Compiling 1 source file to C:apressgswm-bookchapter5gswm argetclasses
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.197s
[INFO] Finished at: Mon Oct 13 22:11:42 MDT 2014
[INFO] Final Memory: 7M/18M
[INFO] ------------------------------------------------------------------------

Goals in Maven are packaged in plug-ins, which are essentially a collection of one or more goals. In Listing 5-1, the compiler is the plug-in that provides the goal compile. Listing 5-2 introduces a pretty nifty goal called clean. As mentioned earlier, the target folder holds Maven-generated temporary files and artifacts. There are times when the target folder becomes huge or when certain files that have been cached need to be cleaned out of the folder. The clean goal accomplishes exactly that, as it attempts to delete the target folder and all its contents.

Listing 5-2. Maven clean Goal

C:apressgswm-bookchapter5gswm>mvn clean:clean
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Getting Started with Maven 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-cli) @ gswm ---
[INFO] Deleting C:apressgswm-bookchapter5gswm arget
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.233s
[INFO] Finished at: Mon Oct 13 22:14:49 MDT 2014
[INFO] Final Memory: 3M/15M
[INFO] ------------------------------------------------------------------------

Notice, the clean:clean suffix of the command in Listing 5-2. The clean before the colon (:) represents the clean plug-in, and the clean following the colon represents the clean goal. By now it should be obvious that running a goal in the command line requires the following syntax:

mvn plugin_identifier:goal_identifier

Plug-ins and their behavior can be configured using the plug-in section of pom.xml. Consider the case where you want to enforce that your project must be compiled with Java 1.6. As of version 3.0, the Maven Compiler Plug-in compiles the code against Java 1.5. Thus, you will need to modify the behavior of this plug-in in the pom.xml file, as shown in Listing 5-3.

Listing 5-3. Plug-in Element in the pom.xml File

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <!-- Project details omitted for brevity -->

  <dependencies>
        <!-- Dependency details omitted for brevity -->
  </dependencies>

  <build>
   <plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.1</version>
      <configuration>
         <source>1.6</source>
         <target>1.6</target>
      </configuration>
    </plugin>
    </plugins>
  </build>
</project>

Now if you were to run the mvn compiler:compile command, the generated class files will be of Java version 1.6.

Image Note  The <build /> element in pom.xml has a very useful child element called finalName. By default, the name of the Maven-generated artifact follows the <<project_artifiact_id>>-<<project_version>> format. However, sometimes you might want to change the name of the generated artifact without changing the artifactId. You can accomplish this by declaring the finalName element as <finalName>new_name</finalName>.

Life Cycle and Phases

Maven follows a well-defined build life cycle when it builds, tests, and distributes an artifact. The life cycle constitutes a series of stages or steps that get executed in the same order, independent of the artifact being produced. Maven refers to the steps in a life cycle as phases. Maven has the following three built-in life cycles:

  • Default: This life cycle handles the compiling, packaging, and deployment of a Maven project.
  • Clean: This life cycle handles the deletion of temporary files and generated artifacts from the target directory.
  • Site: This life cycle handles the generation of documentation and site generation.

Image Note  Now that you are aware of the clean life cycle, you can clean the target folder simply by running the clean phase using the command mvn clean.

To better understand the build life cycle and its phases, let’s look at the some of the phases associated with the default life cycle:

  • Validate: Runs checks to ensure that the project is correct and that all dependencies are downloaded and available.
  • Compile: Compiles the source code.
  • Test: Runs unit tests using frameworks. This step doesn’t require that the application be packaged.
  • Package: Assembles compiled code into a distributable format, such as JAR or WAR.
  • Install: Installs the packaged archive into a local repository. The archive is now available for use by any project running on that machine.
  • Deploy: Pushes the built archive into a remote repository for use by other teams and team members.

Because the default life cycle clearly defines the ordering of the phases, you can generate an artifact simply by running the command mvn package. Maven will automatically execute all of the phases prior to the requested phase. In the provided example, Maven will run phases, such as compile and test, prior to running the package phase. This means developers and configuration managers only have to learn and use a handful of commands.

A number of tasks need to be performed in each phase. For that to happen, each phase is associated with one or more goals. The phase simply delegates those tasks to its associated goals. Figure 5-1 shows the association between life cycle, phases, goals, and plug-ins.

9781484208427_Fig05-01.jpg

Figure 5-1. Association between life cycle, phases, goals, and plug-ins

The <packaging /> element in the pom.xml file will automatically assign the right goals for each of the phases without any additional configuration. Remember that this is a benefit of CoC. If the packaging element contains the value jar, then the package phase will be bound to the jar goal in the jar plug-in. Similarly, for a WAR artifact, pom.xml will bind the package to a war goal in the war plug-in.

SKIPPING TESTS

As discussed earlier, when you run the package phase, the test phase is also run and all of the unit tests get executed. If there are any failures in the test phase, the build fails. This is the desired behavior. However, there are times, for example, when dealing with a legacy project, where you would like to skip running the tests so you can build a project successfully. You can achieve this using the maven.test.skip property. Here is an example of using this property:

mvn package –Dmaven.test.skip=true

Plug-in Development

Developing plug-ins for Maven is very straightforward. This section explains how to develop an example HelloPlugin that will give you a taste of plug-in development.

As discussed earlier, a plug-in is simply a collection of goals. Thus, when we talk about plug-in development, we are essentially talking about developing goals. In Java, these goals are implemented using MOJOs, which stands for Maven Old Java Object and it is similar to Java’s Plain Old Java Object (POJO).

Let’s start this plug-in development by creating a Maven Java project, named gswm-plugin, as shown in Figure 5-2. We are creating this project under a starter gswm-plugin project available in the C:apressgswm-bookchapter5 folder.

9781484208427_Fig05-02.jpg

Figure 5-2. Maven project for plug-in development

Image Note  In this chapter we are manually creating the plug-in project. Maven provides a mavan-archetype-mojo, which would jumpstart your plug-in development. We will learn about Maven archetypes in Chapter 6.

The content of the pom.xml file is shown in Listing 5-4. Notice that the packaging type is maven-plugin. We added the maven-plugin-api dependency, because it is needed for plug-in development.

Listing 5-4. The pom.xml with plug-in api dependency

<?xml version="1.0" encoding="UTF-8"?><project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.apress.plugins</groupId>
    <artifactId>gswm-plugin</artifactId>
    <version>1.0.0</version>
    <packaging>maven-plugin</packaging>
    <name>Simple Hello Plugin</name>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>3.2.3</version>
        </dependency>
    </dependencies>
</project>

The next step in the development process is creating the MOJO. Listing 5-5 shows the code for HelloMojo. As you can see, the implementation is straightforward. We are using the Log instance to log output to the console. The most important part of this code is actually inside the Java comment section: @goal hello. Using the Javadoc tag @goal, we are declaring the name of this goal as hello. It is also possible to use Java 5 annotations such has @Mojo to provide this metadata. However, it requires the pom.xml file changes discussed on the Apache Maven web site (http://maven.apache.org/plugin-tools/maven-plugin-plugin/examples/using-annotations.html).

Listing 5-5. HelloMojo Java Class

package com.apress.plugins;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

/**
 *
 * @goal hello
 */
public class HelloMojo extends AbstractMojo{

        public void execute() throws MojoExecutionException, MojoFailureException {
                getLog().info("Hello Maven Plugin");
        }

}

The final step in this process is installing the plug-in in the Maven repository. Run the mvn install command at the root of the directory and you should get the output shown in Listing 5-6.

Listing 5-6. Maven install Command

C:apressgswm-bookchapter5gswm-plugin>mvn install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Simple Hello Plugin 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-plugin-plugin:3.2:descriptor (default-descriptor) @ gswm-plugin
 ---
[INFO] Applying mojo extractor for language: java-annotations
[INFO] Mojo extractor for language: java-annotations found 0 mojo descriptors.
[INFO] Applying mojo extractor for language: java
[INFO] Mojo extractor for language: java found 1 mojo descriptors.
[INFO] Applying mojo extractor for language: bsh
[INFO] Mojo extractor for language: bsh found 0 mojo descriptors.
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ gswm-plugi
n ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources,
i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:apressgswm-bookchapter5gswm-pluginsrcmainresources
[INFO]
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ gswm-plugin -
--
--------------------------------------------
[INFO] Building jar: C:apressgswm-bookchapter5gswm-plugin argetgswm-plugin-1.0.0.jar
[INFO]
[INFO] --- maven-plugin-plugin:3.2:addPluginArtifactMetadata (default-addPluginA
rtifactMetadata) @ gswm-plugin ---
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ gswm-plugin ---
[INFO] Installing C:apressgswm-bookchapter5gswm-plugin argetgswm-plugin-1.0.0.jar to C:Users<<USER_NAME>>.m2 epositorycomapresspluginsgswm-plugin1.0.0gswm-plugin-1.0.0.jar
[INFO] Installing C:apressgswm-bookchapter5gswm-pluginpom.xml to C:Users<<USER_NAME>>.m2 epositorycomapresspluginsgswm-plugin1.0.0gswm-plugin-1.0.0.pom

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.788s
[INFO] Finished at: Mon Oct 13 22:29:55 MDT 2014
[INFO] Final Memory: 13M/32M
[INFO] ------------------------------------------------------------------------

Now you’re ready to start using this plug-in. Remember that the syntax to run any goal is mvn pluginId:goalId. Listing 5-7 shows this plug-in in action. Notice the Hello Maven Plugin text on the console.

Listing 5-7. Running the Hello Plug-in

C:apressgswm-bookchapter5gswm-plugin>mvn com.apress.plugins:gswm-plugin:hello
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------------------------------------------
[INFO] Building Simple Hello Plugin 1.0.0
[INFO] ----------------------------------------------------------
[INFO] --- gswm-plugin:1.0.0:hello (default-cli) @ gswm-plugin ---
[INFO] Hello Maven Plugin
[INFO] ----------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ----------------------------------------------------------
[INFO] Total time: 0.583s
[INFO] Finished at: Mon Oct 13 22:32:55 MDT 2014
[INFO] Final Memory: 4M/15M
[INFO] ----------------------------------------------------------

Summary

Maven uses plug-in–based architecture that allows its functionality to be extended easily. Each plug-in is a collection of one or more goals that can be used to execute tasks, such as compiling source code or running tests. Maven ties goals to phases. Phases are typically executed in a sequence as part of a build life cycle. You also learned the basics of creating a plug-in.

In the next chapter, you will be introduced to archetypes and learn about multimodule projects.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.91.47