Book Image

Apache Maven 2 Effective Implementation

By : Brett Porter, Maria Odea Ching
Book Image

Apache Maven 2 Effective Implementation

By: Brett Porter, Maria Odea Ching

Overview of this book

<p>By building up a sample application, this book guides developers painlessly through building a project with Maven. This book shows you how to combine Maven with Continuum and Archiva, which will allow you to build an efficient, secure application and make developing in a team easy.<br /><br />You may already be aware of the pitfalls of 'integration hell' caused by changed code being submitted to repositories by a number of developers. When you implement Continuum in your build, you can easily perform continuous integration, avoiding timely rework and reducing cost and valuable time. You will be able to use Maven more efficiently in a team after you learn how to set up Archiva, Apache's repository manager.<br /><br />It's easy to quickly get to work with Maven and get the most out of its related tools when you follow the sequential coverage of the sample application in this book. A focus on team environments ensures that you will avoid the pitfalls that are all too common when working in a team. Soon, by learning the best practices of working with Maven, you will have built an effective, secure Java application.</p>
Table of Contents (21 chapters)
Apache Maven 2 Effective Implementation
Credits
About the Authors
About the Reviewers
Preface
Free Chapter
1
Maven in a Nutshell
Index

Reconfiguring default life cycle goals


One of the most interesting features that has appeared in Maven 2.2.0 and above is the ability to add configuration specifically to the goal execution supplied by default lifecycle bindings.

Previously, you could only do this at the plugin level, for example:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.4.3</version>
  <configuration>
    <excludes>
      <exclude>**/selenium/**</exclude>
    </excludes>
  </configuration>
</plugin>

There are two problems with this:

  1. It may not be appropriate for all goals in the plugin to take this configuration. This is a common problem with the Compiler plugin, where you may want different parameters for the compile and testCompile goals (such as the JDK level—a problem well known by TestNG users developing on JDK 1.4!)

  2. You can't erase configuration through inheritance—so as the example above shows, you are stuck with those excludes even if you define a new goal to run a second set of tests

Consider the addition of the following to the above:

<profile>
  <id>selenium</id>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <executions>
          <execution>
            <id>selenium-tests</id>
            <configuration>
              <includes>
                <include>**/selenium/**</include>
              </includes>
            </configuration>
            <goals>
              <goal>test</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</profile>

This will do nothing, as only the Selenium tests are to be run (includes), but all Selenium tests are disabled (by inheritance of excludes).

This leads to a convoluted combination of turning off the default binding and re-adding it with its configuration, as a modification to the first sample:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.4.3</version>
  <configuration>
    <skip>true</skip>
  </configuration>
  <executions>
    <execution>
      <id>unit-tests</id>
      <configuration>
        <skip>false</skip>
        <excludes>
          <exclude>**/selenium/**</exclude>
        </excludes>
      </configuration>
      <goals>
        <goal>test</goal>
      </goals>
    </execution>
  </executions>
</plugin>

The skip flag also needed to be added to the Selenium profile.

Note

This example is also discussed in the section Running integration tests using naming patterns in Chapter 4, Application Testing with Maven.

Maven 2.2.0 added a simple solution for this problem. All of the executions in the default lifecycle are assigned IDs of the form default-phase. Because Maven's inheritance merges executions with identical IDs, you can assign configuration directly to the built in goal and no others.

This means that the previous section can be reduced to be closer to the original, like so:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.4.3</version>
  <executions>
    <execution>
      <id>default-test</id>
      <configuration>
        <excludes>
          <exclude>**/selenium/**</exclude>
        </excludes>
      </configuration>
    </execution>
  </executions>
</plugin>

The goals are not necessary in the execution, as they were already given in the default binding.

This results in a more intuitive pattern for setting up multiple test executions (a common occurrence with profiles and integration tests), as well as use cases such as configuring the Compiler plugin's main and test compilation goals separately.

However, there is one more thing to watch out for. Taking advantage of this will mean the build is no longer compatible with earlier versions of Maven. To make sure you are not caught out, you should add the Enforcer plugin somewhere in the build:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <version>1.0-beta-1</version>
  <executions>
    <execution>
      <id>enforce</id>
      <goals>
        <goal>enforce</goal>
      </goals>
      <configuration>
        <rules>
          <requireMavenVersion>[2.2.0,)</requireMavenVersion>
        </rules>
      </configuration>
    </execution>
  </executions>
</plugin>

In addition to changing the defaults, you can also now supply configuration that is targeted at command line invocations (without affecting the main build). More information on all of these can be found at http://maven.apache.org/guides/mini/guide-default-execution-ids.html.