maven 子module与工程管理

  实际项目过程中,我们的工程往往是多个模块组合在一起,甚至相互之间也会有依赖关系,如何管理好这些依赖是一个很重要的技能。

  举个简单的场景,web工程mavenWeb与java工程mavenJava都属于一个项目里的模块,而且mavenWeb依赖于mavenJava,通常,我们会建立一个父pom来管理这样的工程。

---------------------------->

  绝大多数时候我都会直接用eclipse插件所提供的快速建maven工程来选择新建web或者java,但命令还是很重要的。创建过程中遇到了问题:

mvn archetype:create -DgroupId=com.changjiang.test -DartifactId=mavenJava -DpackageName=com.changjiang.test

但出现报错:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:2.4:create (default-cli) on project standalone-pom: Unable to pars
e configuration of mojo org.apache.maven.plugins:maven-archetype-plugin:2.4:create for parameter #: Abstract class or interface 'org.apache.maven
.artifact.repository.ArtifactRepository' cannot be instantiated -> [Help 1]

参照了网上的解决方案:

* JAVA_HOME没有设置或者设置有误、m2_home设置有误
* 删除/org/apache/maven/plugins/下的maven-archetype-plugin
* archetype:create命令已经过期,需要使用 archetype:generate 来进行代替(方案可行)
* maven-archetype-plugin 2.3版本的插件有问题,换其它版本进行创建(方案可行)

于是改用generate替代create(maven版本3.0.5),命令行交互mode出现,选择一些基本信息后,创建成功:

mvn archetype:generate -DgroupId=com.changjiang.test -DartifactId=mavenJava -DpackageName=com.changjiang.test

---------------------------->

  接着用命令创建一个mavenWeb工程:

mvn archetype:generate -DgroupId=com.changjiang.web -DartifactId=mavenWeb -DpackageName=com.changjiang.web -DarchetypeArtifactId=maven-archetype-webapp

其过程与mavenJava类似;

 ---------------------------->

  接下来,我们将工程修改符合eclipse要求的结构:

mvn eclipse:eclipse
=====================================
mvn eclipse:eclipse -DwtpVersion=2.0

导入eclipse。结构如下:

  ---------------------------->

  如果我们不用一个父pom来管理这两个模块,那么当mavenWeb需要依赖mavenJava时,就必须在打包多次,如果有多个模块,这个操作就会非常复杂。这里引入pom对这两个模块进行管理。

...
<packaging>pom</packaging>
    <properties>
        <version>1.0</version>
    </properties>
    <modules>
        <module>mavenWeb</module>
        <module>mavenJava</module>
    </modules>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

子项目里:

...
        <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.changjiang.maven</groupId>
        <artifactId>mavenParent</artifactId>
        <version>1.0</version>
    </parent>
...

这样,只要在mavenParent中进行mvn install的操作,它就会对所有的模块进行自动打包处理。

  除了子模块的统一入口,父pom另一个作用就是依赖的遗传,设置统一的<dependency/>并在<properties/>中标注版本,即可统一管理所有的公共依赖和它们的版本。

...
        <module>CHiQ3-web</module>
      <module>CHiQ3-rest</module>
  </modules>
  
  <properties>
          
          <javax.ws.rs-api.version>2.0</javax.ws.rs-api.version>
          <resteasy-client.version>3.0.16.Final</resteasy-client.version>
          <dubbo.version>2.8.4</dubbo.version>
          <commons-logging.version>1.2</commons-logging.version>
          <slf4j-log4j12.version>1.7.7</slf4j-log4j12.version>
          <junit.version>4.11</junit.version>
          <mockito.version>1.9.5</mockito.version>
          <fastjson.version>1.2.7</fastjson.version>
        <mongodb.version>3.2.0</mongodb.version>
        <spring.version>4.2.4.RELEASE</spring.version>
        <spring-dao.version>2.0.8</spring-dao.version>
        <spring-data-mongo.version>1.8.2.RELEASE</spring-data-mongo.version>
        <druid.version>1.0.14</druid.version>
        <zookeeper.version>3.4.6</zookeeper.version>
        <zkclient.version>0.5</zkclient.version>
        <aspect.version>1.8.7</aspect.version>
        <javassist.version>3.20.0-GA</javassist.version>
        <mysql.version>5.1.38</mysql.version>
        <httpclient.version>4.5.1</httpclient.version>
        <commons-collections.version>3.2.1</commons-collections.version>
        <jackson-annotations.version>2.6.3</jackson-annotations.version>
        <!-- Plugin的属性定义 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jdk.version>1.7</jdk.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <javax.servlet-api.version>3.1-b08</javax.servlet-api.version>
  </properties>
  
  <dependencies>
        <!-- restful api -->
              <dependency>
                <groupId>javax.ws.rs</groupId>
                <artifactId>javax.ws.rs-api</artifactId>
                <version>${javax.ws.rs-api.version}</version>
            </dependency>
        <!-- 嵌入式容器 -->
            <dependency>
                <groupId>org.jboss.resteasy</groupId>
                <artifactId>resteasy-client</artifactId>    
...

子pom中也可以像在父pom中确定依赖的版本。

  如果各个子模块之间也有依赖关系,比如我们提到的这个场景,mavenWeb依赖于mavenJava,那么也可以在父pom中用<dependencyManagement/>进行管理。

 需要特别注意的是,父pom中所定义的各种参数,子pom可以用${}来引用,但是<parent/>里面不能用通配符。

 ---------------------------->

  当然,父pom中的<plugin/>也是会被继承的。相对的,也会有<pluginManagement/>可以保证子pom中所有的版本,配置一致。

  另外,对于maven依赖冲突时,maven有自己的规则来进行排序,比如同级的相同依赖,按在pom中出现的先后排序;不同级的依赖,就近原则。

  如果在继承的过程中,发现有依赖中部分的依赖不想被继承,就要用到<exclusions/>:

...
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.1.0.Final</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.transaction</groupId>
                    <artifactId>jta</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>

---------------------------->

  在添加诸如spring等的依赖时,往往会用到一些依赖所依赖的jar包,这个时候最好能够将已经引用到,但是没有放到pom中的依赖放到pom中去。可以用mvn dependency:resolve来查询已经依赖的jar包和文件:

E:UsersBruceChanworkspacedev01mavenParent>mvn dependency:resolve
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] mavenParent
[INFO] mavenJava
[INFO] mavenWeb Maven Webapp
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building mavenParent 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.1:resolve (default-cli) @ mavenParent ---
[INFO]
[INFO] The following files have been resolved:
[INFO]    antlr:antlr:jar:2.7.7:compile
[INFO]    com.fasterxml:classmate:jar:1.3.0:compile
[INFO]    dom4j:dom4j:jar:1.6.1:compile
[INFO]    junit:junit:jar:4.11:test
[INFO]    org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1.1:compile
[INFO]    org.hamcrest:hamcrest-core:jar:1.3:test
[INFO]    org.hibernate:hibernate-core:jar:5.1.0.Final:compile
[INFO]    org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile
[INFO]    org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO]    org.javassist:javassist:jar:3.20.0-GA:compile
[INFO]    org.jboss:jandex:jar:2.0.0.Final:compile
[INFO]    org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile
[INFO]    xml-apis:xml-apis:jar:1.0.b2:compile
[INFO]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building mavenJava 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.1:resolve (default-cli) @ mavenJava ---
[INFO]
[INFO] The following files have been resolved:
[INFO]    antlr:antlr:jar:2.7.7:compile
[INFO]    com.fasterxml:classmate:jar:1.3.0:compile
[INFO]    dom4j:dom4j:jar:1.6.1:compile
[INFO]    junit:junit:jar:4.11:test
[INFO]    org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1.1:compile
[INFO]    org.hamcrest:hamcrest-core:jar:1.3:test
[INFO]    org.hibernate:hibernate-core:jar:5.1.0.Final:compile
[INFO]    org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile
[INFO]    org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO]    org.javassist:javassist:jar:3.20.0-GA:compile
[INFO]    org.jboss:jandex:jar:2.0.0.Final:compile
[INFO]    org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile
[INFO]    xml-apis:xml-apis:jar:1.0.b2:compile
[INFO]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building mavenWeb Maven Webapp 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.1:resolve (default-cli) @ mavenWeb ---
[INFO]
[INFO] The following files have been resolved:
[INFO]    antlr:antlr:jar:2.7.7:compile
[INFO]    com.changjiang.test:mavenJava:jar:1.0:compile
[INFO]    com.fasterxml:classmate:jar:1.3.0:compile
[INFO]    dom4j:dom4j:jar:1.6.1:compile
[INFO]    javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO]    junit:junit:jar:4.11:test
[INFO]    org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1.1:compile
[INFO]    org.hamcrest:hamcrest-core:jar:1.3:test
[INFO]    org.hibernate:hibernate-core:jar:5.1.0.Final:compile
[INFO]    org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile
[INFO]    org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO]    org.javassist:javassist:jar:3.20.0-GA:compile
[INFO]    org.jboss:jandex:jar:2.0.0.Final:compile
[INFO]    org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile
[INFO]    xml-apis:xml-apis:jar:1.0.b2:compile
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] mavenParent ....................................... SUCCESS [1.148s]
[INFO] mavenJava ......................................... SUCCESS [0.216s]
[INFO] mavenWeb Maven Webapp ............................. SUCCESS [0.220s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.210s
[INFO] Finished at: Thu Aug 25 15:18:28 CST 2016
[INFO] Final Memory: 9M/244M
[INFO] ------------------------------------------------------------------------

  ---------------------------->

对于平时用到比较多的依赖,可以整理一个专门的pom来存放这些依赖,在使用的时候,直接引用这个pom就可以了。

<dependency>
    <groupId>com.xxx</groupId>
    <artifactId>xxx</artifactId>
    <version>xxx</version>
    <type>pom</type>
</dependency>

不过采用这种方式存在依赖性的问题。

  这种依赖性的问题,总体来说就是有共享的信息,多用依赖,没有共享的信息,就用多模块处理。

原文地址:https://www.cnblogs.com/bruceChan0018/p/5793923.html