一个多maven项目聚合的实例

原文: http://my.oschina.net/xuqiang/blog/99854

本文介绍一个多maven项目的实例demo,展示了聚合、继承、工程依赖、单元测试、多war聚合、cargo发布等场景 
一、工程介绍 
该项目由5个maven项目组成 
 
task-aggregator是父工程,同时承担聚合模块和父模块的作用,没有实际代码和资源文件  task-common是基础工程,里面是公共的代码  task-sla是某一个业务子模块,不包含web内容  task-sla-web是某一个web子模块  task-web-dist是最外围的web工程,聚合多个web工程,形成最终的war包 
依赖关系是:task-common <-- task-sla <-- task-sla-web <-- task-web-dist 
二、task-aggregator 
 
这个工程是起到聚合作用,并充当parent pom,所以没有任何实际代码和资源文件。我这里选择了平行结构,另外一种方式是树形结构,我个人感觉平行结构看起来更舒服一点 
下面是pom,有所简化:

Xml代码           

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <!-- 定义公共变量 -->
  4. <properties>
  5. <spring.version>3.1.0.RELEASE</spring.version>
  6. <struts2.version>2.3.1</struts2.version>
  7. <hibernate.version>3.2.7.ga</hibernate.version>
  8. </properties>
  9. <modelVersion>4.0.0</modelVersion>
  10. <groupId>com.huawei.inoc.wfm.task</groupId>
  11. <artifactId>task-aggregator</artifactId>
  12. <version>0.0.1-SNAPSHOT</version>
  13. <packaging>pom</packaging>
  14. <!-- 待聚合模块 -->
  15. <modules>
  16. <module>../task-common</module>
  17. <module>../task-sla</module>
  18. <module>../task-sla-web</module>
  19. <module>../task-web-dist</module>
  20. </modules>
  21. <!-- 配置部署的远程仓库 -->
  22. <distributionManagement>
  23. <snapshotRepository>
  24. <id>nexus-snapshots</id>
  25. <name>nexus distribution snapshot repository</name>
  26. <url>http://10.78.68.122:9090/nexus-2.1.1/content/repositories/snapshots/</url>
  27. </snapshotRepository>
  28. </distributionManagement>
  29. <build>
  30. <pluginManagement>
  31. <plugins>
  32. <plugin>
  33. <groupId>org.apache.maven.plugins</groupId>
  34. <artifactId>maven-resources-plugin</artifactId>
  35. <version>2.6</version>
  36. <configuration>
  37. <encoding>UTF-8</encoding>
  38. </configuration>
  39. </plugin>
  40. <plugin>
  41. <groupId>org.apache.maven.plugins</groupId>
  42. <artifactId>maven-compiler-plugin</artifactId>
  43. <version>2.5.1</version>
  44. <configuration>
  45. <encoding>UTF-8</encoding>
  46. </configuration>
  47. </plugin>
  48. </plugins>
  49. </pluginManagement>
  50. </build>
  51. <dependencyManagement>
  52. <dependencies>
  53. <dependency>
  54. <groupId>com.sun</groupId>
  55. <artifactId>tools</artifactId>
  56. <version>1.6.0</version>
  57. <scope>system</scope>
  58. <systemPath>${env.JAVA_HOME}/lib/tools.jar</systemPath>
  59. </dependency>
  60. </dependencies>
  61. </dependencyManagement>
  62. </project>

基本上是一目了然,只是有几点注意下: 
    1、这里配置了<distributionManagement>,这样子项目就不需要重复配置了 
    2、通过<pluginManagement>,对一些插件进行了公共的配置,这里主要是为了消除构建时的告警 
    3、配置tools,是因为实际中发现,其他开发人员从svn上check out工程以后,有的人会报错,找不到tools.jar,这样配置以后就好了 
三、task-common 
该工程是公共工程,提供了项目中的公共代码,这里只包括了通用的DAO组件,作为示例。 
该工程不依赖任何其他工程 
 
该工程里有几点要点: 
    1、在代码内部用了Spring的注解

Java代码           

  1. public abstract class GenericDAO<T> implements IGenericDAO<T> {
  2. private Class<T> entityClass;
  3. public GenericDAO(Class<T> clazz) {
  4. this.entityClass = clazz;
  5. }
  6. @Autowired
  7. private HibernateTemplate hibernateTemplate;
  8. }

这里用到了@Autowired注解,所以最终形成的war包,必须在spring配置文件中声明HibernateTemplate类型的bean,否则会报错 
我这里用的maven环境是maven3.0.4,这个版本打出的jar包,带有Directory Entries信息,所以spring的注解即使在jar包中也可生效,如果是比较老的版本,spring的注解在jar包中不好用,关于这个问题的详细描述,见另外一篇博客:http://kyfxbl.iteye.com/blog/1675368 
    2、单元测试的写法

Java代码           

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = "classpath:spring-test.xml")
  3. @Transactional
  4. public class GenericDAOTest {
  5. @Autowired
  6. private IBookDAO bookDAO;
  7. @Test
  8. public void testInsert() {
  9. Book book = new Book();
  10. book.setName("thinking in java");
  11. book.setIsbn("111");
  12. bookDAO.insert(book);
  13. }
  14. }

这里用到了几个注解,@RunWith是为了在spring容器环境下跑这个单元测试类,以支持依赖注入。@ContextConfiguration是声明spring配置文件的位置。@Transactional注解之后,在单元测试方法中的事务会自动回滚,这个比较方便,这样在前面执行的方法,不会对后面的方法造成影响 
这个单元测试类,可以直接在maven里跑起来,让我比较惊喜。之前这样写,在ant里跑没有成功,可能是我没有找到合适的插件的原因 
    3、除了测试的java代码之外,还有3个资源文件,都是放在src/test/resources下,这些资源文件只在test阶段生效,package阶段不会被打包,也就是专门供测试阶段使用 
这个各有利弊,优点是测试的配置文件与开发的配置文件隔离,互不干扰。缺点是配置文件似乎缺少了集中放置的地点,这样如果多个maven工程都需要跑单元测试,要共享测试用配置文件,比较麻烦一点 
不过从我个人来看,也算是利大于弊。只是在每个maven项目下,都需要独立的测试相关资源文件,其实也有利于分别修改 
另外,可以看到这里的hibernate映射文件,不是和model类放在一个package下,而是放在resources目录下的,这样做可以避免一些潜在的问题,也有利于后续的聚合 
    4、pom文件没有什么特别的,只是要引入<scope>为test的junit和spring-test 
四、task-sla 
该工程依赖task-common(因为用到了GenericDAO),是某一个业务模块的逻辑部分,包含了数据库访问层和业务逻辑层,但是不包括web相关的部分 
 
这里没有什么特别要注意的,目录结构和task-common基本一样。比较特别的是可以看到Maven Dependencies里,有一个task-common工程,所以task-common里的任何修改,都可以第一时间在这个工程里体现出来,是比较方便的 
关于这个问题,见另外一篇博客:http://kyfxbl.iteye.com/blog/1679806 
另外就是前面说过的,hibernate的映射文件,应该放在src/main/resources下,而不是与Model类放在一起 
五、task-sla-web 
这个工程是上述task-sla工程的web层,依赖于task-sla,由于task-sla又依赖task-common,所以这个工程最终会同时依赖task-common和task-sla 
 
然后这个工程里包含了web层的东西,包括Action类、jsp、图片、struts2的配置文件等,这些东西放在web工程里是最合适的 
 
这里需要注意2点: 
    1、这个工程的packaging类型是war,而不是jar。但是最终它不会独立打出war包来,其src/main/webapp里的所有文件,都会被最外围的task-web-dist工程聚合成一个总的war 
    2、这个工程的WEB-INF目录下,没有web.xml(有也没用,最终会被覆盖)。默认情况下,packaging类型为war的项目,如果没有web.xml,则构建会失败,因此需要在pom里做一个配置 
该项目的pom如下,省略了依赖部分:

Xml代码           

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  3. <parent>
  4. <groupId>com.huawei.inoc.wfm.task</groupId>
  5. <artifactId>task-aggregator</artifactId>
  6. <version>0.0.1-SNAPSHOT</version>
  7. <relativePath>../task-aggregator</relativePath>
  8. </parent>
  9. <modelVersion>4.0.0</modelVersion>
  10. <artifactId>task-sla-web</artifactId>
  11. <packaging>war</packaging>
  12. <build>
  13. <plugins>
  14. <plugin>
  15. <groupId>org.apache.maven.plugins</groupId>
  16. <artifactId>maven-war-plugin</artifactId>
  17. <configuration>
  18. <failOnMissingWebXml>false</failOnMissingWebXml>
  19. </configuration>
  20. </plugin>
  21. </plugins>
  22. </build>
  23. <!-- 配置依赖 -->
  24. <dependencies>
  25. <dependency>
  26. <groupId>org.springframework</groupId>
  27. <artifactId>spring-beans</artifactId>
  28. </dependency>
  29. </dependencies>
  30. </project>

上面的<failOnMissingWebXml>,就是配置缺少web.xml也不使构建失败 
六、task-web-dist 
这个工程是最外围的web工程,起到聚合的作用,即把所有的web项目,打成最终的war包。同时,在这个工程里,放置里公共的配置文件,比如struts.xml、ssoconfig.properties等 
 
这个工程的聚合意图十分明显,比如struts.xml

Xml代码           

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
  3. <struts>
  4. <constant name="struts.objectFactory" value="spring" />
  5. <constant name="struts.ui.theme" value="simple" />
  6. <constant name="struts.i18n.encoding" value="UTF-8" />
  7. <constant name="struts.action.extension" value="action" />
  8. <constant name="struts.enable.DynamicMethodInvocation" value="false" />
  9. <constant name="struts.devMode" value="true" />
  10. <include file="struts2/struts-sla.xml" />
  11. </struts>

提供了项目通用的配置,并把各子项目的struts2配置文件聚合起来。war包中的web.xml也是在这里提供的 
下面是该工程的pom,也省略了依赖的配置:

Xml代码           

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  3. <parent>
  4. <groupId>com.huawei.inoc.wfm.task</groupId>
  5. <artifactId>task-aggregator</artifactId>
  6. <version>0.0.1-SNAPSHOT</version>
  7. <relativePath>../task-aggregator</relativePath>
  8. </parent>
  9. <modelVersion>4.0.0</modelVersion>
  10. <artifactId>task-web-dist</artifactId>
  11. <packaging>war</packaging>
  12. <build>
  13. <finalName>task</finalName>
  14. <plugins>
  15. <!-- 合并多个war -->
  16. <plugin>
  17. <groupId>org.apache.maven.plugins</groupId>
  18. <artifactId>maven-war-plugin</artifactId>
  19. <configuration>
  20. <packagingExcludes>WEB-INF/web.xml</packagingExcludes>
  21. <overlays>
  22. <overlay>
  23. <groupId>com.huawei.inoc.wfm.task</groupId>
  24. <artifactId>task-sla-web</artifactId>
  25. </overlay>
  26. </overlays>
  27. </configuration>
  28. </plugin>
  29. <!-- 利用cargo启动容器 -->
  30. <plugin>
  31. <groupId>org.codehaus.cargo</groupId>
  32. <artifactId>cargo-maven2-plugin</artifactId>
  33. <version>1.2.3</version>
  34. <configuration>
  35. <container>
  36. <containerId>tomcat7x</containerId>
  37. <home>D:\apache-tomcat-7.0.29</home>
  38. </container>
  39. <configuration>
  40. <type>standalone</type>
  41. <home>${project.build.directory}/tomcat7.0.29</home>
  42. <properties>
  43. <cargo.jvmargs>
  44. -Xdebug
  45. -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787
  46. </cargo.jvmargs>
  47. </properties>
  48. </configuration>
  49. </configuration>
  50. <executions>
  51. <execution>
  52. <id>cargo-run</id>
  53. <phase>pre-integration-test</phase>
  54. <goals>
  55. <goal>run</goal>
  56. </goals>
  57. </execution>
  58. </executions>
  59. </plugin>
  60. </plugins>
  61. </build>
  62. </project>

这里主要是对maven-war-plugin和cargo-maven2-plugin这2个插件进行了配置,以起到聚合war,以及通过cargo启动容器的作用
关于多war聚合,以及cargo,见另外2篇博客:http://kyfxbl.iteye.com/blog/1678121、http://kyfxbl.iteye.com/blog/1677608 
七、启动构建 
在task-aggregator目录下,执行mvn clean deploy或者mvn clean install,就可启动整个构建过程,并将容器启动起来,跑最终生成的war包 

时间: 2024-10-12 06:03:14

一个多maven项目聚合的实例的相关文章

使用maven构建一个helloworld maven项目

1.下载maven http://maven.apache.org/ 选择一个较新版本下下来 2.配置m2_home环境变量 先解压,新建用户变量m2_home,将bin目录添加到path变量中 3.测试是否安装成功:mvn -version 4.在某个目录下输入mvn archetype:generate,要等一会儿 第一次要下载不少jar包,到 Generating project in Interactive mode 时要等很久不要关,继续等 5.让你输入groupid:com.hy 输

Eclipse创建一个普通maven项目详细步骤

首先找到Eclipse最顶部左边的File,new一个 Maven Project项目 下一步,勾选第二个即可 下一步,选择  maven-archetype-webapp Group Id 写域名倒置+公司名,如com.ali,  Artifact Id写项目名,然后点击finish 刚创建完的项目会报错 打开jsp页面,提示是这个错误The superclass "javax.servlet.http.HttpServlet" was not found on the Java B

一个基于Maven项目Ant的构建模板

一般的我创建的项目都是基于Maven的,但是很多人也喜欢用Ant打包jar,或者war.我一般都会在项目中既包含Maven的pom.xml,也会有ant的build.xml 只要在控制台执行: ? 1 mvn dependency:copy-dependencies 然后执行: ? 1 ant OR ant javadoc 就会打包程序或者生成项目的Javadoc文档. 打包的程序一般在:${project.path}/target/dist/${version}/ JavaDoc文档一般在${

Maven学习笔记(三):Maven的聚合和继承

Maven的聚合其实就是把各个项目拷贝到一个项目里,便于统一构建(这种是父子目录结构构件,个人喜欢这种,平行结构不喜欢),实现聚合的方式为: -- 新建一个普通的Maven项目,只保留pom文件,其他的目录结构都删除 -- 配置新建项目的pom文件: 1 <project ...> 2 <modelVersion>4.0.0</modelVersion> 3 <groupId>XXXX</groupId> 4 <artifactId>

多模块Maven项目如何使用javadoc插件生成文档

需求 最近要对一个项目结构如下的Maven项目生成JavaDoc文档. Project |-- pom.xml |-- Module1 |   `-- pom.xml |-- Module2 |   `-- pom.xml |-- Module3 |-- pom.xml 这个就需要用到本文将要提出的一个Maven插件:javadoc. 基本使用 插件的基本配置很简单: <plugin> <groupId>org.apache.maven.plugins</groupId>

IntelliJ IDEA 15 创建maven项目

原文:IntelliJ IDEA 15 创建maven项目 说明 创建Maven项目的方式:手工创建 好处:参考IntelliJ IDEA 14 创建maven项目二(此文章描述了用此方式创建Maven项目的好处)及idea14使用maven创建web工程(此文章描述了用模板创建Maven的弊端.) 创建一个新Maven项目 new 一个project 不选择任何Maven模板 起个GroupId.ArifactId 起个项目名.注意:Idea_Project是存放此项目的工作区间,mavenD

idea 创建多模块依赖Maven项目

转载地址: http://www.cnblogs.com/tibit/p/6185704.html idea 创建多模块依赖Maven项目 本来网上的教程还算多,但是本着自己有的才是自己的原则,还是自己写一份的好,虽然可能自己也不会真的用得着. 1. 创建一个新maven项目 2. 3. 输入groupid和artifactid,后面步骤直接next,最后finish 4.创建好后 5. 在主项目名称上点右键,创建第一个子模块 6 7 8 同理,在创建一个模块,创建好后 9 打开Project

【IntelliJ 】IntelliJ IDEA 15 创建maven项目

说明 创建Maven项目的方式:手工创建 好处:参考IntelliJ IDEA 14 创建maven项目二(此文章描述了用此方式创建Maven项目的好处)及idea14使用maven创建web工程(此文章描述了用模板创建Maven的弊端.) 创建一个新Maven项目 new 一个project 不选择任何Maven模板 起个GroupId.ArifactId 起个项目名.注意:Idea_Project是存放此项目的工作区间,mavenDemo_idea15为存放此项目的子目录. 建好项目后,打开

Eclipse从git导入Maven项目

1.入职新公司第一天,因为以前用的是svn管理代码版本所以对git不是很了解. 先不介绍git的特点,简单的说一下自己最后摸索出来的笨办法 需要Eclipse建立两个工作空间一个做maven项目,一个做git项目 首先Eclipse导入git项目, 然后Eclipse另建工作空间导入maven项目,注意代码与git项目路径保持一致. Eclipse集成git管理代码版本使用:  pull  commit  push 2.今天碰到maven项目导入后,jar包更新不全,后由经理提供新setting