【问题标题】:Multi-module maven build : different result from parent and from module多模块Maven构建:来自父模块和模块的不同结果
【发布时间】:2012-11-29 10:30:09
【问题描述】:

我正在将应用程序从 ant build 迁移到 maven 3 build。 这个应用程序是由:

  • 指定要构建的所有模块的父项目
  • 使用 jaxb 生成类并使用它们构建 jar 的项目
  • 构建 ejb 项目的项目
  • 3 个构建战争模块的项目
  • 1个项目建设耳朵

这是我父母 pom 的摘录:

<groupId>com.test</groupId>
<artifactId>P</artifactId>
<packaging>pom</packaging>
<version>04.01.00</version>

<modules>
    <module>../PValidationJaxb</module> <-- jar
    <module>../PValidation</module> <-- ejb
    <module>../PImport</module> <-- war
    <module>../PTerminal</module> <-- war
    <module>../PWebService</module> <-- war
    <module>../PEAR</module> <-- ear
</modules>

我有几个我认为有相同根源的问题,可能是我无法弄清楚的依赖管理问题:

  • 生成的模块会有所不同,具体取决于我是从父 pom 构建还是单个模块构建。通常,如果我只构建 PImport,生成的战争类似于我的 ant 构建,如果我从父 pom 构建,我的战争需要 20MB,添加了许多来自其他模块的依赖项。两场战争都进展顺利。

  • 我的项目 PWebService 具有要在构建期间执行的单元测试。它使用以 cglib 作为依赖项的 mock-ejb。这个有 ClassNotFound 问题,我不得不排除它并向 cglib-nodep 添加一个依赖项(参见最后一个 pom 提取)。如果我只构建这个模块,它运行良好。但是如果我从父项目构建,它会失败,因为其他模块中的其他依赖项也对 cglib 有隐式依赖。我不得不在每个模块 pom 中排除它,并将依赖项添加到 cglib-nodep 中以使其运行。

我是否遗漏了配置中的重要内容?

PValidation pom 提取:

它正在创建一个 jar,其中包含一个带有由 xdoclet 生成的接口的 ejb,以及一个客户端 jar。

<parent>
    <groupId>com.test</groupId>
    <artifactId>P</artifactId>
    <version>04.01.00</version>
</parent>
<artifactId>P-validation</artifactId>
<packaging>ejb</packaging>

<dependencies>
    <dependency>
        <groupId>com.test</groupId>
        <artifactId>P-jaxb</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate</artifactId>
        <version>3.2.5.ga</version>
        <exclusions>
            <exclusion>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib-nodep</artifactId>
        <version>2.2.2</version>
    </dependency>
    ...
    [other libs]
    ...
</dependencies>

<build>
    ...
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ejb-plugin</artifactId>
            <configuration>
                <ejbVersion>2.0</ejbVersion>
                <generateClient>true</generateClient>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>xdoclet-maven-plugin</artifactId>
            ...

PImport pom 提取物:

这取决于 Jaxb 生成的 jar 和 ejb 客户端 jar。

<parent>
    <groupId>com.test</groupId>
    <artifactId>P</artifactId>
    <version>04.01.00</version>
</parent>
<artifactId>P-import</artifactId>
<packaging>war</packaging>

<dependencies>
    <dependency>
        <groupId>com.test</groupId>
        <artifactId>P-jaxb</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>com.test</groupId>
        <artifactId>P-validation</artifactId>
        <version>${project.version}</version>
        <type>ejb-client</type>
    </dependency>
    ...
    [other libs]
    ...
</dependencies>

PWebService pom 提取:

<parent>
    <groupId>com.test</groupId>
    <artifactId>P</artifactId>
    <version>04.01.00</version>
</parent>

<artifactId>P-webservice</artifactId>
<packaging>war</packaging>

<properties>
    <jersey.version>1.14</jersey.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-servlet</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>com.rte.etso</groupId>
        <artifactId>etso-validation</artifactId>
        <version>${project.version}</version>
        <type>ejb-client</type>
    </dependency>
    ...
    [other libs]
    ...
    <dependency>
        <groupId>org.mockejb</groupId>
        <artifactId>mockejb</artifactId>
        <version>0.6-beta2</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>cglib</groupId>
                <artifactId>cglib-full</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib-nodep</artifactId>
        <version>2.2.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

非常感谢

修改配置后的解决方法:

当我得到已经 mavenized 的项目时,它不尊重文件夹布局约定,但正如它在 pom 中声明的那样可以找到源代码,我认为它会起作用。 不管怎样,我改变了它以匹配推荐的结构。

为了构建单个模块,我直接在其级别执行 mvn clean install。就是这样我得到了不同的结果(这实际上是我想要的结果)。

无论如何,我的问题已经解决了,我将 PValidation 项目的所有依赖项都按提供的方式放置,因为我只是将生成的客户端包含在其他模块中,它们不需要实现所需的所有内容。

但我仍然不明白为什么相同的配置会有不同的结果。

【问题讨论】:

    标签: maven maven-3


    【解决方案1】:

    首先重要的是您应该创建适合模块结构的项目结构,这意味着具有以下文件夹结构:

    +-- parent
          +-- PValidationJaxb
          +-- PValidation
          +-- PImport
          +-- PTerminal
          +-- PWebService
          +-- PEAR
    

    这意味着有一个 pom.xml,其中包含父文件夹中的模块定义。 如果您遵循上述建议,您可以将模块列表简化为以下内容:

    <modules>
        <module>PValidationJaxb</module> <-- jar
        <module>PValidation</module> <-- ejb
        <module>PImport</module> <-- war
        <module>PTerminal</module> <-- war
        <module>PWebService</module> <-- war
        <module>PEAR</module> <-- ear
    </modules>
    

    此外,Maven 中的最佳实践是使用 小写工件,这意味着在您的情况下是 pvalidationjaxb 而不是 PValidationJaxb

    另一个重要的事情是您的版本不遵循Maven conventions。此外,从 Maven 的角度来看,您的版本将是一个版本,而您正在对此进行开发并非如此。在 Maven 中,您应该将所谓的 SNAPSHOT 用于 1.0.0-SNAPSHOT 等目的。

    我希望你已经按照folder layout recommendation of Maven 的说法将生产代码(将被打包到生成的 jar 中)放入 src/main/java 而测试代码放入 src/测试/java.

    您描述的具有不同依赖项的问题听起来很奇怪。问题是您如何尝试构建单个模块?这通常可以通过使用父位置的以下内容来实现:

    mvn -pl module clean package
    

    您的单元测试的问题听起来像是缺少依赖项等,但这里的问题是您如何尝试运行单元测试并配置 maven-surefire-plugin ?或者你有集成测试吗?这只是一个猜测,因为我在你的 poms 中没有看到任何 Maven 插件配置。

    【讨论】:

    • 我的配置确实有问题,我编辑了问题的结尾以解释它是什么。谢谢
    猜你喜欢
    • 2014-06-01
    • 1970-01-01
    • 2019-07-11
    • 2019-10-07
    • 1970-01-01
    • 2013-02-23
    • 2015-02-25
    • 2010-11-09
    相关资源
    最近更新 更多