在典型的 J2EE 环境中,WAR 封装在 EAR 中以进行部署。WAR 可以在WEB-INF/lib中包含其所有依赖的 JAR,但是如果有多个 WAR,由于存在重复的 JAR,EAR 会很快变得非常大。相反,J2EE 规范允许 WAR 通过MANIFEST.MF中的Class-Path设置来引用打包在 EAR 中的外部 JAR 。
Maven WAR 和 EAR 插件不直接支持这种操作模式,但我们可以通过一些 POM 和配置魔术来伪造它。首先,您需要告诉 Maven 排除依赖的 JAR,并改为在MANIFEST.MF中添加对它们的引用。这将进入您的 WAR 项目的pom.xml:
<project> ... <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <!-- In version 2.1-alpha-1, this was incorrectly named warSourceExcludes --> <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> </manifest> </archive> </configuration> </plugin> </plugins> </build> ... </project>
这是上述示例的另一个变体,但这次我们使用<packagingIncludes>来选择一些要包含在 WAR 中的 JAR。当需要将一个小的但非空的 JAR 子集打包到 WAR 中时,这很有用。在制作一个瘦 WAR 的 EAR 时,希望将所有 JAR 打包到 EAR 中。有时,为了使其正常工作,必须将 JAR 列表打包到 WAR 中,就像使用标记库一样。
<project> ... <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <!-- Use this to include a selection of jars that will be included in the WAR --> <packagingIncludes>WEB-INF/lib/my-tag-library.jar,**/*.xml,**/*.properties,**/*.class,**/*.png,**/*.css,**/*.js,**/*.jsp</packagingIncludes> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> </manifest> </archive> </configuration> </plugin> </plugins> </build> ... </project>
接下来我们需要更改 EAR 项目的pom.xml以将那些依赖的 JAR 打包到 EAR 中。请注意,我们将所有内容打包到EAR 中的lib/目录中。这只是我个人对区分 J2EE 模块(将被打包在 EAR 的根目录中)和 Java 库(将被打包在lib/中)的偏好。
... <build> <plugins> <plugin> <artifactId>maven-ear-plugin</artifactId> <version>2.3.2</version> <configuration> <defaultLibBundleDir>lib/</defaultLibBundleDir> </configuration> </plugin> </plugins> </build> ...
现在是痛苦的部分。您的 EAR 项目的pom.xml需要列出 WAR 具有的每个依赖项。这是因为 Maven 假定胖 WAR 并且不包括 EAR 中 WAR 的传递依赖。
.... <dependencies> <dependency> <groupId>com.acme</groupId> <artifactId>shared-jar</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.acme</groupId> <artifactId>war1</artifactId> <version>1.0.0</version> <type>war</type> </dependency> <dependency> <groupId>com.acme</groupId> <artifactId>war2</artifactId> <version>1.0.0</version> <type>war</type> </dependency> </dependencies> ...
您的 EAR 将包含如下内容:
. |-- META-INF | `-- application.xml |-- lib | `-- shared-jar-1.0.0.jar |-- war1-1.0.0.war `-- war2-1.0.0.war
我们的用户已在 Wiki上提交了上述配方的替代方案。