如何让 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 中的企业应用程序中管理依赖关系变得更加容易。它将所有传递依赖项捆绑到以上是关于如何让 Maven 将战争常见的所有罐子放在同一个 EAR 到 EAR 根目录中?的主要内容,如果未能解决你的问题,请参考以下文章
如何让 Weblogic 10 更喜欢 myApp.war:/WEB-INF/lib/ 中的罐子而不抛出 VerifyErrors?