Learning Maven 2 - A Multi-module Project


we create a multimodule project that combines the examples from the two previous examples in <Learning Maven 1>. The simpleWeather code developed , Customizing a Maven Project will be combined with the simpleWeb project, A Simple Web Application to create a web application that retrieves and displays weather forecast information on a web page. At the end of this artical, you will be able to use Maven to develop complex, multimodule projects.


The directory named weather-webapp/, which contains the multimodule Maven project developed in this artical. In this directory, you will see a pom.xml and the two submodule directories, simpleWeather/ and simpleWeb/.



一、The Simple Parent Project

A multimodule project is defined by a parent POM referencing one or more submodules. In theweather-webapp directory, you will find the parent POM (also called the top-level POM) inweather-webapp/ pom.xml. 

<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>
<!--
  <parent>
    <groupId>org.ftcl.multi</groupId>                                                                                                                                
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
-->
  <groupId>org.ftcl.multi</groupId>
  <artifactId>weather-webapp</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Multi Chapter Simple Parent Project</name>
  <url>http://maven.apache.org</url>

  <modules>
    <module>simpleWeather</module>
    <module>simpleWeb</module>
  </modules>

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

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Notice that the parent defines a set of Maven coordinates: the groupId is org.ftcl.multi, the artifactId is weather-webapp, and the version is 1.0.The parent project doesn’t create a JAR or a WAR like our previous projects; instead, it is simply a POM that refers to other Maven projects. The appropriate packaging for a project like weather-webapp that simply provides a Project Object Model is pom. The next section in the pom.xml lists the project’s
submodules. These modules are defined in the modules element, and each module element corresponds to a subdirectory of theweather-webapp/ directory. Maven knows to look in these directories for pom.xml files, and it will add submodules to the list of Maven projects included in a build.


Lastly, we define some settings which will be inherited by all submodules. The weather-webapp build configuration configures the target for all Java compilation to be the Java 6 JVM. Since the compiler plugin is bound to the lifecycle by default, we can use the pluginManagement section do to this. We will discuss pluginManagement in more detail in later articals, but the separation between providing configuration to default plugins and actually binding plugins is much easier to see when they are separated this way. The dependencies element adds JUnit 3.8.1 as a global dependency.Both the build configuration and the dependencies are inherited by all submodules. 


二、The Simple Weather Module

The first submodule we’re going to look at is the simpleWeather submodule. This submodule contains all of the classes that take care of interacting with and parsing the Yahoo! Weather feeds.

<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>

  <parent>
    <groupId>org.ftcl.multi</groupId>
    <artifactId>weather-webapp</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
<!--
  <groupId>org.ftcl</groupId>
-->
  <artifactId>simpleWeather</artifactId>
  <packaging>jar</packaging>

  <name>Multi Simple Weather API</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  	<dependency>
  	  <groupId>log4j</groupId>
  	  <artifactId>log4j</artifactId>
  	  <version>1.2.16</version>
  	</dependency>
  	<dependency>
  	  <groupId>dom4j</groupId>
  	  <artifactId>dom4j</artifactId>
  	  <version>1.6.1</version>
  	</dependency>
	<dependency>
	  <groupId>jaxen</groupId>
	  <artifactId>jaxen</artifactId>
	  <version>1.1.4</version>
	</dependency>
	<dependency>
	  <groupId>velocity</groupId>
	  <artifactId>velocity</artifactId>
	  <version>1.5</version>
	</dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <pluginManagement>
  	  <plugins>
  	    <plugin>
  	  	  <groupId>org.apache.maven.plugins</groupId>
  	  	  <artifactId>maven-surefire-plugin</artifactId>
  	  	  <configuration>
  	  	    <testFailureIgnore>true</testFailureIgnore>
  	  	  </configuration>
  	    </plugin>
  	  </plugins>
  	</pluginManagement>
  </build>
</project>

注意,子pom.xml中一定不要<groupId></groupId>,否则会出错。

In simple-weather’s pom.xml file, we see this module referencing a parent POM using a set of Maven coordinates. The parent POM for simpleWeather is identified by a groupId of org.ftcl.multi, an artifactId of weather-webapp, and a version of 1.0. 

 “The WeatherService class”:

package org.ftcl.weather;
                                                                                            
import java.io.InputStream;

public class WeatherService {

    public WeatherService() {}

    public String retrieveForecast( String zip ) throws Exception {
    // Retrieve Data
    InputStream dataIn = new YahooRetriever().retrieve( zip );

    // Parse Data
    Weather weather = new YahooParser().parse( dataIn );

    // Format (Print) Data
    return new WeatherFormatter().format( weather );
    }
}

We’re creating a separate project that contains service objects that are referenced in the web application project. This is a common model in enterprise Java development; often a complex application consists of more than just a single, simple web application. 


三、The Simple Web Application Module

The simpleWeb module is the second submodule referenced in the simple-parent project. This web application project depends upon the simpleWeather module, and it contains some simple servlets that present the results of the Yahoo! weather service query.

simpleWebapp Module POM:

<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>
  <parent>
    <groupId>org.ftcl.multi</groupId>
    <artifactId>weather-webapp</artifactId>
    <version>1.0</version>
  </parent>
 <!--
  <groupId>org.ftcl.webapp</groupId>
 -->
  <artifactId>simpleWeb</artifactId>
  <packaging>war</packaging>
  <version>1.0</version>
  <name>Multi Simple Web Maven Web Application Project</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
    	<groupId>org.jboss.spec.javax.servlet</groupId>
    	<artifactId>jboss-servlet-api_3.0_spec</artifactId>
    	<version>1.0.2.Final</version>
    	<scope>provided</scope>
   	</dependency>
   	<dependency>
	  <groupId>org.ftcl.multi</groupId>
	  <artifactId>simpleWeather</artifactId>
	  <version>${project.version}</version>
    </dependency>
   	<dependency>
   		<groupId>org.apache.tomcat</groupId>
   		<artifactId>jsp-api</artifactId>
   		<version>6.0.35</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>simpleWeb</finalName>
    <plugins>
	  <plugin>
	    <groupId>org.mortbay.jetty</groupId>
	    <artifactId>maven-jetty-plugin</artifactId>
	    <version>6.1.26</version>
	  </plugin>
	</plugins>
  </build>
</project>

注意,子pom.xml中一定不要<groupId></groupId>,否则会出错。


 This simpleWeb module defines a very simple servlet that reads a zip code from an HTTP request, calls the WeatherService, “The WeatherService class”, and prints the results to the response’s Writer.

package org.ftcl.webapp.web;

import org.ftcl.weather.WeatherService; //此类在simpleWeather工程的相应包中
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class WeatherServlet extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws ServletException, IOException {
	String zip = request.getParameter("zip" );
	WeatherService weatherService = new WeatherService();
	PrintWriter out = response.getWriter();
        try {
	    out.println( weatherService.retrieveForecast( zip ) );
	} catch( Exception e ) {
	    out.println( "Error Retrieving Forecast: " + e.getMessage() );
	}
        out.flush();
        out.close();
    }
}

Finally, to tie all of this together is the web.xml for simple-webapp in src/main/webapp/WEB-INF. The servlet and servlet-mapping elements in the web.xml, “simpleWeb web.xml” map the request path /weather to the WeatherServlet.
simpleWeb web.xml:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
	<servlet-name>simple</servlet-name>
	<servlet-class>org.ftcl.webapp.web.SimpleServlet</servlet-class>
  </servlet>
  <servlet>
	<servlet-name>weather</servlet-name>
	<servlet-class>org.ftcl.webapp.web.WeatherServlet</servlet-class>
  </servlet>
  <servlet-mapping>
	<servlet-name>simple</servlet-name>
	<url-pattern>/simple</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
	<servlet-name>weather</servlet-name>
	<url-pattern>/weather</url-pattern>
  </servlet-mapping>
</web-app>


四、Building the Multimodule Project

With the simpleWeb project containing all the general code for interacting with the Yahoo! Weather service and the simpleWeb project containing a simple servlet, it is time to compile and package the application into a WAR file. To do this, you will want to compile and install both projects in the appropriate order; since simpleWeb depends on simpleWeather, the simpleWeather JAR needs to be created before the simpleWeb project can compile. To do this, you will run mvn clean install command from the weatherWeb project:


mvn clean install

When Maven is executed against a project with submodules, Maven first loads the parent POM and locates all of the submodule POMs. Maven then puts all of these project POMs into something called the Maven Reactor which analyzes the dependencies between modules. The Reactor takes care of ordering components to ensure that interdependent modules are compiled and installed in the proper order.

Once the Reactor figures out the order in which projects must be built, Maven then executes the specified goals for every module in a multi-module build. In this example, you can see that Maven builds simpleWeather before simpleWeb effectively executing mvn clean install for each submodule.


五、Running the Web Application

Once the multimodule project has been installed with mvn clean install from the parent project, weather-webapp, you can then change directories into the simpleWeb project and run the Run goal of the Jetty plugin:



Once Jetty has started, load http://localhost:8080/simpleWeb/weather?zip=01201 in a browser and you should see the formatted weather output.


六、再建立一个parent pom

现在的parent pom为weather-webapp/目录下的pom,现在建立此pom的parent pom。设weather-webapp的父目录为multi.在muti目录下建立pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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>org.ftcl.multi</groupId>
  <artifactId>parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>Multi Chapter Parent Project</name>                                                                                                                          
  <modules>
    <module>weather-webapp</module>
  </modules>
</project>

此时需要改动一下weather-webapp中pom.xml的内容,为其添加<parent></parent>以及删除<groupId><groupId>:

<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>

  <parent>
    <groupId>org.ftcl.multi</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
 <!--
  <groupId>org.ftcl.multi</groupId>
 -->
  <artifactId>weather-webapp</artifactId>
  <version>1.0-SNAPSHOT</version>
 <packaging>pom</packaging> 

  <name>Multi Chapter Simple Parent Project</name>
  <url>http://maven.apache.org</url>

  <modules>
    <module>simpleWeather</module>
    <module>simpleWeb</module>
  </modules>

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

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值