Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

developerWorks Community:

  • Close [x]

Introduction to Apache Maven 2

Sing Li (westmakaha@yahoo.com), Author, Wrox Press
Photo of Sing Li
Sing Li is a consultant and an active author with more than two decades of industry experience. He has contributed to Professional Apache Geronimo, Beginning JavaServer Pages, Professional Apache Tomcat 5, Pro JSP - Third Edition, Early Adopter JXTA, Professional Jini, Beginning J2ME: From Novice to Professional, Third Edition, Professional Apache Geronimo, and numerous other books. Sing also writes for technical magazines and participates in open source communities. He is an evangelist of the open source, VOIP, and P2P movements. You can reach Sing at westmakaha@yahoo.com.

Summary:  Modern software projects are no longer solely monolithic creations of single local project teams. With the increased availability of robust, enterprise-grade open source components, today's software projects require dynamic collaboration among project teams and often depend on a mix of globally created and maintained components. Now in its second generation, the Apache Maven build system -- unlike legacy build tools created before the Internet-enabled era of global software development -- was designed from the ground up to take on these modern challenges. This tutorial gets you started with Maven 2.

Date:  19 Dec 2006
Level:  Intermediate

Activity:  152623 views
Comments:  

Hands-on Maven 2: Working with multiple project builds

Building and testing simple projects using Maven 2 is straightforward. This section examines a second example demonstrating the more realistic and common case of a multiple-modules project.

Extending the NumOps example

The NumOps example is extended in this second example. A new SubOps class is added to support subtraction, and a new MulOps class is added to support multiplication.

However, the Operation interface and the AddOps class are now removed from the NumOps project. Instead, they are placed together with the new SubOps and MulOps classes in a new project called OpsImp. Figure 7 shows this relationship between the NumOps and OpsImp projects:


Figure 7. Relationship between NumOps and OpsImp
Relationship between NumOps and OpsImp

Dependencies among subprojects and submodules within a larger project is a frequently occurring scenario in software development. You can apply the technique shown here to any multimodule Maven project with interdependencies.

SubOps, shown in Listing 13, is coded similarly to AddOps. MulOps, not shown here, is similar; you can take a look at the code distribution for details (see Download).


Listing 13. The new SubOps class implementing the Operation interface
                    
package com.ibm.devworks;

public class SubOps implements Operation {
   public int op(int a, int b) {
      return a-b;
   }
   public String getDesc() {
      return "minus";
   }
}

The constructor of NumOps has now been modified to create an instance of SubOps and an instance of MulOps. See the source code distribution for details.


Creating a master project

To work with these two projects, a master project has been created one directory above the NumOps and the OpsImp project directories. Both the NumOps and OpsImp projects use the standard Maven project directory layout. At the top level, the project directory consists of only a pom.xml file. Figure 8 shows the new sub-directory structure, immediately under the master directory:


Figure 8. Directory structure for a multimodule project
Directory structure for a multi-module project

You can find the code for this multimodule project in the example2 subdirectory of the code distribution (see Download). The top-level pom.xml file is shown in Listing 14:


Listing 14. The top level pom.xml for the multimodule project
                    
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.ibm.devworks</groupId>
  <artifactId>mavenex2</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Maven Example 2</name>
  <url>http://maven.apache.org</url>
<modules>
 <module>NumOps</module>
 <module>OpsImp</module>
</modules>
   <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>   
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
<dependencyManagement>
                    <dependencies>
                        <dependency>
                          <groupId>com.ibm.devworks</groupId>
                          <artifactId>OpsImp</artifactId>
                          <version>${project.version}</version>
                        </dependency>
                      </dependencies>
                    </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

The new code is highlighted in bold. First, the artifact ID of this master project is mavenex2, and its packaging type is pom. This signals to Maven 2 that this is a multimodule project.

The <modules> tag then specifies the two modules that this project comprises: NumOps and OpsImp.

The submodules of this master project can inherit properties from this pom.xml file. More specifically, none of the submodules needs to declare JUnit as a dependency, even though they both contain unit tests. This is because they inherit the JUnit dependency defined at this top level.

The <dependencyManagement> tag does not specify dependencies that this module depends on. Instead, it is used mainly by submodules. Submodules can specify a dependency on any of the entries within the <dependencyManagement> tag without specifying a specific version number. This is useful for minimizing the number of edits required when a tree of projects changes dependency version numbers. In this case, the OpsImp project's version number is specified using ${project.version} This is a parameter that will be filled with the appropriate value during Maven execution.


Inheriting from a master POM

Descending one level to the OpsImp directory, the pom.xml file for this module is shown in Listing 15:


Listing 15. The pom.xml file for the new OpsImp project
                    
<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/maven-v4_0_0.xsd">
  <parent>
   <groupId>com.ibm.devworks</groupId>
    <artifactId>mavenex2</artifactId>
    <version>1.0-SNAPSHOT</version>
   </parent> 
  <modelVersion>4.0.0</modelVersion>
  <artifactId>OpsImp</artifactId>
  <packaging>jar</packaging>
 </project>

The <parent> element specifies the master POM that this module inherits from. Inheriting from the parent module simplifies this pom.xml greatly. All that is necessary is to override the artifact ID and packaging. This module inherits the parent's dependency: the JUnit module.

The NumOps pom.xml also inherits from the parent and is also quite simple. This pom.xml is shown in Listing 16:


Listing 16. The pom.xml for the NumOps project showing POM inheritance
                    
<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/maven-v4_0_0.xsd">
  <parent>
   <groupId>com.ibm.devworks</groupId>
    <artifactId>mavenex2</artifactId>
    <version>1.0-SNAPSHOT</version>
   </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>NumOps</artifactId>
  <packaging>jar</packaging>
  <dependencies>
                        <dependency>
                          <groupId>com.ibm.devworks</groupId>
                          <artifactId>OpsImp</artifactId>
                         </dependency>
                      </dependencies>
</project>

Discovering the effective POM

Whenever you are inheriting from a higher-level POM, you can always find out what your equivalent pom.xml looks like after all the inherited elements have been accounted for. The command to show the "effective POM" is mvn help:effective-pom. You'll see some elements that you have not specified yourself. These are inherited from the Super POM. Every project pom.xml inherits implicitly from Maven's built-in Super POM.

The interesting item in the NumOps POM is the specification of the OpsImp project as a dependency. Note that no version number is specified in this dependency. The preferred version number is already specified within the parent's <dependencyManagement> element.

At the top-level project, you can now issue the mvn compile command to compile both modules or mvn test to run the unit tests of both modules. You can also run mvn install to install the packaged modules to your local directory. This allows any modules that depend on it to resolve the dependency without requiring access to the source code.

9 of 15 | Previous | Next

Comments



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, Open source
ArticleID=184162
TutorialTitle=Introduction to Apache Maven 2
publish-date=12192006
author1-email=westmakaha@yahoo.com
author1-email-cc=