多模块项目的结构化。如何打包模块?

时间:2013-07-15 08:04:16

标签: maven java-ee

我用maven创建了一个多模块项目的结构。 父母的pom:

<?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/xsd/maven-   4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>cat.base.gpt</groupId>
  <artifactId>gpt</artifactId>
  <version>0.0.1</version> <!-- application version -->
  <packaging>pom</packaging>
  <name>gpt</name>

  <parent>
        <groupId>cat.base.baseframe</groupId>
        <artifactId>projecte-pare-baseframe</artifactId>
        <version>0.0.11.a</version>
  </parent>

  <modules>
    <module>gpt.domini</module>
    <module>gpt.ui</module>
    <module>gpt.logica</module>
    <module>gpt.ejb</module>
    <module>gpt.ear</module>
  </modules>
  <dependencies>
  <!-- dependencies pel testeig TDD -->
          <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>1.9.5-rc1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.kubek2k</groupId>
            <artifactId>springockito</artifactId>
            <version>1.0.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.4</version>
            <scope>provided</scope>
        </dependency>
    <!--  A més, en el cas de provatures UI, s'ha d'afegir la següent dependència:-->
        <dependency>
            <groupId>cat.base.baseframe</groupId>
            <artifactId>baseframe-test-swf</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <scope>test</scope>
        </dependency>
       </dependencies>
  </project>

好的,第一个问题,我将所有依赖项放在paren的pom上这是否真的正确?

和最有趣的部分,我不知道如何编译grafic interfade项目,(我称之为ui),最好创建一个战争或创建和耳朵所有必要的(ui + logica + domini + ejb)我对这一点感到困惑,我使用已经构建的项目。我希望你能理解我的问题,我把剩下的pom留意了。 TY。

pom's gpt.domini. 

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>gpt</artifactId>
    <groupId>cat.base.gpt</groupId>
    <version>0.0.1</version>
  </parent>

  <groupId>cat.base.gpt.domini</groupId>
  <artifactId>gpt.domini</artifactId>
  <packaging>jar</packaging>

  <name>gpt.domini</name>
  <description>Definició del model de dades i de la façana del servei</description>
  </project>

pom的gpt.ear

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>gpt</artifactId>
    <groupId>cat.base.gpt</groupId>
    <version>0.0.1</version>
  </parent>

  <groupId>cat.base.gtp.ear</groupId>
  <artifactId>gpt.ear</artifactId>
  <name>gpt.ear</name>


  <packaging>ear</packaging>
  <description>Paquet de l'aplicació J2EE</description>

  <dependencies>
        <dependency>
            <groupId>${project.parent.groupId}</groupId>
            <artifactId>${project.parent.artifactId}.domini</artifactId>
            <version>${project.parent.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>${project.parent.groupId}</groupId>
            <artifactId>${project.parent.artifactId}.ejb</artifactId>
            <version>${project.parent.version}</version>
            <type>ejb</type>
        </dependency>
        <dependency>
            <groupId>${project.parent.groupId}</groupId>
            <artifactId>${project.parent.artifactId}.logica</artifactId>
            <version>${project.parent.version}</version>
            <type>jar</type>
        </dependency>

  </dependencies>
</project>

pom的gpt.logica

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>gpt</artifactId>
    <groupId>cat.base.gpt</groupId>
    <version>0.0.1</version>
  </parent>


  <groupId>cat.base.gtp.logica</groupId>
  <artifactId>gpt.logica</artifactId>
  <name>climbing.logica</name>
  <packaging>jar</packaging>
  <description>Implementació del servei</description>


  <dependencies>
  <!-- de moment nomes el domini -->
    <dependency>
            <groupId>${project.parent.groupId}</groupId>
            <artifactId>${project.parent.artifactId}.domini</artifactId>
            <version>${project.parent.version}</version>
            <scope>provided</scope>
        </dependency>
  </dependencies>
</project>

pom的gpt.ejb

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <artifactId>gpt</artifactId>
    <groupId>cat.base.gpt</groupId>
    <version>0.0.1</version>
  </parent>

  <groupId>cat.base.gtp.ejb</groupId>
  <artifactId>gpt.ejb</artifactId>
  <name>gpt.ejb</name>
  <packaging>ejb</packaging>
  <description>Publicació d'un servei en forma EJB</description>


  <dependencies>
        <dependency>
            <groupId>${project.parent.groupId}</groupId>
            <artifactId>${project.parent.artifactId}.domini</artifactId>
            <version>${project.parent.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>${project.parent.groupId}</groupId>
            <artifactId>${project.parent.artifactId}.logica</artifactId>
            <version>${project.parent.version}</version>
        </dependency>
        <dependency>
            <groupId>${project.parent.groupId}</groupId>
            <artifactId>${project.parent.artifactId}.logica</artifactId>
            <version>${project.parent.version}</version>
            <classifier>tests</classifier>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.ejb</groupId>
            <artifactId>ejb-api</artifactId>
            <version>3.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jboss</groupId>
            <artifactId>jboss-annotations-ejb3</artifactId>
            <version>4.2.2.GA</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>2.5.6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.client</groupId>
            <artifactId>jbossall-client</artifactId>
            <version>4.2.3.GA</version>
            <scope>test</scope>
        </dependency>
  </dependencies>
</project>

pom的gpt.logica

   <?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>gpt</artifactId>
    <groupId>cat.base.gpt</groupId>
    <version>0.0.1</version>
  </parent>


  <groupId>cat.base.gtp.logica</groupId>
  <artifactId>gpt.logica</artifactId>
  <name>climbing.logica</name>
  <packaging>jar</packaging>
  <description>Implementació del servei</description>


  <dependencies>
  <!-- de moment nomes el domini -->
    <dependency>
            <groupId>${project.parent.groupId}</groupId>
            <artifactId>${project.parent.artifactId}.domini</artifactId>
            <version>${project.parent.version}</version>
            <scope>provided</scope>
        </dependency>
  </dependencies>
</project>

pom的gpt.ui

这里所有spring-rich.faces的依赖关系......或者更好的父母的pom? 包装像战争?或者在de module ear? TY。

3 个答案:

答案 0 :(得分:3)

虽然已经有一个公认的答案,但我认为值得向你提供更多信息,因为在我看来,提问者和接受的答案都被Maven中的不同概念搞得一团糟。


1)聚合与父POM

Maven中有两个概念经常混淆。聚合(也称为多模块)POM和父POM是不相关的,尽管使用一个POM来实现这两个目的是可以的。

多模块项目旨在描述项目之间的聚合关系,以便我们可以构建多个相关项目作为一个整体,并且所有子项目都建立在同一个反应堆中。父项目旨在提供共享项目设置。它甚至可以存在于项目结构之外(例如,我可能有一个公司明智的父POM)

我个人建议让多模块POM声明项目的聚合(层次结构),并使用单独的父POM来声明共享设置。

即。

my-proj    // aggregation only
    + my-proj-parent    // parent POM
    + my-proj-main
    + my-proj-web
    + my-proj-ear

2)POM与EAR的共享依赖

同样,这是两个独立的概念。

将依赖项放在父POM中是很好的。当你把它放在那里时,这意味着继承的项目将具有这种依赖性。这方面没有对错,只要你知道自己在做什么(我个人用不同的方式,将在后面描述)。

但是,是否将共享JAR放在EAR中并保持瘦的WAR,或者是否具有“完全”WAR的普通EAR与您的依赖关系无关。它更多的是关于EAR的包装策略。因此,改变Maven依赖的范围只是因为你要将项目打包为瘦战,这样的方法只是搞乱了整个maven依赖的概念。更可怕的是,在创建EAR时,您需要找出其包含的WAR的所有依赖关系并将其逐个添加到EAR POM中,这无疑不是最佳解决方案

遗憾的是,目前的Maven EAR插件仍然没有办法宣布一个瘦弱的战争包装策略。但是,有一些解决方法允许您这样做,而不会弄乱Maven依赖范围。 http://maven.apache.org/plugins/maven-ear-plugin/examples/skinny-wars.html http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html

(更新:瘦的war receipe似乎已更新,其中一个解决方法似乎已消失。http://docs.codehaus.org/display/MAVENUSER/Solving+the+Skinny+Wars+problem?focusedCommentId=212631587#comment-212631587这是包含WAR类型POM作为POM类型,因此我们不需要在EAR中再次声明依赖项)


3)在父POM

中使用共享依赖项

正如我之前提到的,将依赖项放在父级中是没有对错的。但是你应该知道,这种方式实际上意味着所有继承的项目都会有这样的依赖,这大多是不正确的。

例如,我在foo-a下有foo-bfoo个项目,这两个项目都继承了foo-parent。假设foo-a正在使用spring-core,而foo-b的整个逻辑与它无关,如果你把spring-core作为依赖关系放在foo-parent中,当你看foo-b时,它是不可思议的无关的依赖关系spring-core。

正确的方法是在父POM中包含应该在所有继承的项目中共享的依赖项(和其他设置)。例如,单元测试相关的依赖项可能是一个不错的选择。集成测试的依赖性可能是另一个例子。

但是,这并不意味着我们应该单独声明每个项目中的依赖项。最大的问题之一是这种方法很难在整个项目中维护相同版本的依赖项。

为了解决这个问题,我建议在父POM中使用dependencyManagement,它会声明版本(也可能是其他设置,如范围,排除)。声明dependencyManagement不会在继承的POM中引入实际依赖项。它只是声明:“如果你声明这种依赖,这将是要使用的设置”。在每个继承的POM中,只需声明依赖项的组和工件(可能还有一些项目特定的设置),这样就可以遵循父POM中声明的版本。

也许有点难以理解,这是一个例子:

<强> FOO-父

<project>
  <dependencyManagement>  // dependency management doesn't bring actual dependency
    <dependencies>
      <dependency>
         <groupId>org.springframework<groupId>
         <artifactId>spring-core<artifactId>
         <version>3.1.0.RELEASE</version>
      </dependency>
      <dependency>
         <groupId>org.hibernate<groupId>
         <artifactId>hibernate-core<artifactId>
         <version>3.6</version>
      </dependency>
    </dependencies>
  <dependencyManagement>

  <dependencies>    // actual shared dependency
    <dependency>
       <groupId>junit<groupId>
       <artifactId>junit<artifactId>
       <version>4.11</version>
       <scope>test</scope>
    </dependency>
  </dependencies>
  .....
<project>

<强> FOO-A

<project>
  <dependencies>
    <dependency> // note: no version declared
      <groupId>org.springframework<groupId>
      <artifactId>spring-core<artifactId>
    </dependency>

    // junit dependency is inherited
  <dependencies>
<project>

答案 1 :(得分:2)

  

好的,第一个问题,我把所有的依赖关系放在了paren的pom上   真的对吗?

不,您的共享依赖项应放在耳中。在其他poms中,您必须使用<scope>provided</scope>引用共享依赖项。

例如,在你的耳朵pom中添加一个相关性:

<dependency>
    <groupId>somegroup</groupId>
    <artifactId>someartifact</artifactId>
    <version>1.0</version>
</dependency>

例如,在logica和ui模块pom中添加以下行:

<dependency>
    <groupId>somegroup</groupId>
    <artifactId>someartifact</artifactId>
    <version>1.0</version>
    <scope>provided</scope>
</dependency>

通过这种方式,依赖性工件只在ear包中添加一次。

  

和最有趣的部分,我不知道编译grafic的hos   interfade项目,(我称之为ui),最好创造战争或创造和   所有必要的耳朵(ui + logica + domini + ejb)我是一个小小的   对此感到困惑,我使用已经结构化的项目   创建。我很好地理解我的问题,我把剩下的pom给了   随时关注。 TY。

我不知道我是否理解正确。 EAR更适合可以拥有多个war和/或ejb模块的项目。在你的情况下,你可以完全摆脱模块化,并使用一个war包。

答案 2 :(得分:0)

最后这是我的耳朵。

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>gpt</artifactId>
    <groupId>cat.base.gpt</groupId>
    <version>0.0.1</version>
  </parent>

  <groupId>cat.base.gpt.ear</groupId>
  <artifactId>gpt.ear</artifactId>
  <name>gpt.ear</name>


  <packaging>ear</packaging>
  <description>Paquet de l'aplicació J2EE</description>

  <dependencies>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>gpt.domini</artifactId>
            <version>${project.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>gpt.ejb</artifactId>
            <version>${project.version}</version>
            <type>ejb</type>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>gpt.logica</artifactId>
            <version>${project.version}</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>gpt.ui</artifactId>
            <version>${project.version}</version>
            <type>war</type>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ear-plugin</artifactId>
                <configuration>
                    <description>GPT</description>
                    <displayName>Gestió posicions tributarias</displayName>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <version>1.4</version>
                    <generateApplicationXml>true</generateApplicationXml>
                    <modules>
                        <ejbModule>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>${project.parent.artifactId}.ejb</artifactId>
                            <bundleFileName>${project.parent.artifactId}-ejb.jar</bundleFileName>
                        </ejbModule>
                        <jarModule>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>gpt.logica</artifactId>
                            <includeInApplicationXml>true</includeInApplicationXml>
                        </jarModule>                        

                        <webModule>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>gpt.ui</artifactId>
                            <contextRoot>/gpt</contextRoot>
                        </webModule>
                    </modules>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <configuration>
                    <excludeScope>runtime</excludeScope>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>