如何让 Maven 将战争常见的所有罐子放在同一个 EAR 到 EAR 根目录中?

Posted

技术标签:

【中文标题】如何让 Maven 将战争常见的所有罐子放在同一个 EAR 到 EAR 根目录中?【英文标题】:How to make maven place all jars common to wars inside the same EAR to EAR root? 【发布时间】:2010-10-25 08:07:18 【问题描述】:

我们有无数次战争的解决方案。战争在他们都使用hibernate和spring的意义上是相似的。这意味着我们在每场战争中都有许多相同的罐子。这已经成为一个问题,因为耳朵的大小开始变得不成比例。

我想使用 Maven 来计算依赖关系,并将多个战争共有的所有 jar 放到 EAR 的根目录中。

我尝试使用 j2ee 原型 (maven-archetype-j2ee-simple) 组织我的项目,但所有战争仍然与 WEB-INF/lib 中的依赖项打包在一起。 有没有办法让 Maven 计算公共依赖项并将它们放置到 EAR 中,就像他在构建战争或 jar 时能够计算所有过渡依赖项一样?

【问题讨论】:

【参考方案1】:

您可以将dependancies scope 设置为“已提供”。这意味着它们将由其他模块提供,不会包含在最终的 jar 或战争中。

也许assembly plugin 可以帮助您打包最终的 EAR 并将常用的罐子放在那里。

【讨论】:

【参考方案2】:

http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html

【讨论】:

来自建议的 URL:“现在是痛苦的部分。您的 EAR 项目的 pom.xml 需要列出 WAR 具有的每个依赖项。这是因为 Maven 假定胖 WAR 并且不包括 WAR 的传递依赖项耳朵。”我问:我想用maven计算依赖...不使用maven计算依赖,不行... @Dan,阅读 Turbokiwi 的回答,了解如何以极好的方式避免痛苦的部分 :)【参考方案3】:

创建一个名为 commons-jars 的新工件并将其打包为 pom。它应该取决于您使用的所有常见 jar - Spring、Hibernate、Log4j 等。

然后,在您的每次战争中将其添加为具有“已提供”范围的依赖项(并且不要忘记将类型设置为 pom)。您将能够在您的类路径中看到它,但它们不会被打包到战争中。这样,您还可以将特定于战争的依赖项打包到其中,skinny wars 的解决方案不提供。

【讨论】:

那么在我们创建 commons-jars.jar 之后,我们应该将它添加到 1)server/default/lib 还是 2)ear root 中? 不是最好的方法,看下一个答案! @toefel 请定义“下一个”答案。 WHOM 或链接的回答会有所帮助,因为他们可能会根据投票情况更换位置。【参考方案4】:

正如您在评论中提到的,计算每个依赖项是 maven 的任务。当您创建具有每个常见依赖项的工件时,您还必须猜测哪些依赖项属于那里。

也有可能,你必须部署一场战争,它依赖于另一台没有耳朵的机器,当你将每个战争依赖项设置为提供时,你又被卡住了。

获得瘦身战争的唯一正确方法是来自示例: http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html

但是,现在有趣的部分来了,有一个大的!快捷方式(完全消除了前面提到的痛苦),告诉 maven,你的 WAR 有哪些依赖项。

进入你的 EAR 模块,为每个 WAR 依赖声明第二个对 WAR 的依赖,类型为 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>com.foo</groupId>
    <artifactId>skinny</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ear</artifactId>
<packaging>ear</packaging>
<dependencies>
    <dependency>
        <groupId>com.foo</groupId>
        <artifactId>war</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <type>war</type>
    </dependency>
    <dependency>
        <groupId>com.foo</groupId>
        <artifactId>war</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <type>pom</type>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <version>2.8</version>
            <configuration>
                <skinnyWars>true</skinnyWars>
                <defaultLibBundleDir>lib</defaultLibBundleDir>
                <modules>
                    <webModule>
                        <groupId>com.foo</groupId>
                        <artifactId>war</artifactId>
                    </webModule>
                </modules>
            </configuration>
        </plugin>
    </plugins>
</build>

现在,每个 WAR 都将使用它自己的依赖项独立打包,EAR 将与瘦 WAR 和 lib 文件夹中的每个依赖项一起打包

更新:

请记住,ear/lib 文件夹不能用于 JBoss EAP 6 等严格容器中的每个依赖 jar。像 tomahawk、primefaces 等 JSF 组件库必须驻留在 WEB-INF/lib文件夹。

使用上述解决方案实现此目的的一种简便方法是在 EARs pom.xml 中排除组件库,如下所示:

...
<dependencies>
    <dependency>
        <groupId>com.foo</groupId>
        <artifactId>war</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <type>war</type>
    </dependency>
    <dependency>
        <groupId>com.foo</groupId>
        <artifactId>war</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.primefaces</groupId>
                <artifactId>primefaces</artifactId>
            <exclusion>
        </exclusions>
    </dependency>
</dependencies>
...

现在 WAR 的所有依赖项都将放在 ear/lib 中,除了组件库将放在 WAR 内的 WEB-INF/lib 中

【讨论】:

这个真的需要TONS更多的支持!!惊人的 ! :D 不错! :) 这对我很有帮助! 此解决方案是否也适用于更深层次的依赖关系?还是我需要在 WAR 中明确声明工件,以便我可以在 EAR 中排除它们? 这是一个非常巧妙的技巧——它使得在捆绑在 EAR 中的企业应用程序中管理依赖关系变得更加容易。它将所有传递依赖项捆绑到 /lib 目录中,同时仅在根目录捆绑瘦 WAR 文件。赞一个! 这确实有效,应该是最好的答案。它创造了一些很好的隔离。 WAR 的 pom.xml 不必被触及,并且与 EAR 项目保持分离。

以上是关于如何让 Maven 将战争常见的所有罐子放在同一个 EAR 到 EAR 根目录中?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Weblogic 10 更喜欢 myApp.war:/WEB-INF/lib/ 中的罐子而不抛出 VerifyErrors?

Maven继承和聚合

Maven将辅助文件部署到存储库

如何制作一个 Maven 项目的“胖罐子”? [复制]

带有伏地魔罐子的 Maven 存储库

如何将战争合二为一?