maven-war-plugin的行为与标准的maven依赖解析机制有什么不同? 我有一个具有依赖性的war maven项目:
<dependency>
<groupId>GroupA</groupId>
<artifactId>DependencyA</artifactId>
<exclusions>
<exclusion>
<groupId>GroupB</groupId>
<artifactId>DependencyB</artifactId>
</exclusion>
</exclusions>
</dependency>
正确排除了上述依赖关系,我可以在依赖关系层次结构视图上进行验证。
当我用maven构建war时,它包含了WEB-INF/lib
目录中的DependencyB,因此我必须明确定义使用maven-war-plugin将其排除,如下所示:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<packagingExcludes>
WEB-INF/lib/dependencyB.jar,
</packagingExcludes>
</configuration>
</plugin>
我必须做以上原因导致我的项目出现版本之间的冲突。 为什么会这样? 还有另一种方法可以达到这个目的吗?
更新
所以我创建了一个测试用例,只是为了向您展示我的意思,如果我之前不够清楚的话。 相应的pom如下:
ArtifactA:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>GroupA</groupId>
<artifactId>ArtifactA</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>ArtifactA Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>GroupB</groupId>
<artifactId>ArtifactB</artifactId>
<type>war</type>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>GroupC</groupId>
<artifactId>ArtifactC</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>ArtifactA</finalName>
</build>
ArtifactB
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>GroupB</groupId>
<artifactId>ArtifactB</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>ArtifactB Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>GroupC</groupId>
<artifactId>ArtifactC</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>ArtifactB</finalName>
</build>
ArtifactC
<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>GroupC</groupId>
<artifactId>ArtifactC</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ArtifatcC</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
在Eclipse中的依赖项Hierarchy中,我没有看到依赖项ArtifactC。
在构建ArtifactA并解压缩.war时,我得到:
正如您所见,传递依赖包含在WEB-INF / lib的.war中。 我希望现在更清楚了。
要添加的其他一些细节:
答案 0 :(得分:2)
问题不在于war插件以不同方式处理依赖项排除,而是它特别处理<type>war</type>
的依赖项。它创建了一个war overlay,这意味着它需要战争的全部内容,并将项目的Web资源放在首位。 war依赖实际上没有传递依赖,它已经包含了所有jar文件。
如果您真的有意使用战争叠加,那么使用packagingExcludes
是正确的解决方案。如果您想要依赖工件B中的类,那么您应该修改pom,以便创建一个单独的工件(使用attachClasses
configuration)并依赖于此classes
工件。然后,排除传递依赖项应该与任何其他jar依赖项一样。
答案 1 :(得分:0)
我也注意到<exclusions>
的奇怪行为。我最好的建议是把它放在战争项目(项目A)中。
<dependency>
<groupId>GroupC</groupId>
<artifactId>ArtifactC</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
注意范围provided
我必须经常这样做以进行公共记录,因为某些东西似乎总是会导致它被包含在内,而且它只是a $$中的一个痛点,可以在任何地方标记排除。
另一个选择是在项目B中执行此操作:
<dependency>
<groupId>GroupC</groupId>
<artifactId>ArtifactC</artifactId>
<version>0.0.1-SNAPSHOT</version>
<optional>true</optional>
</dependency>
然后在实际需要的地方明确添加ArtifactC和ArtifactB依赖项(即在其他地方部署B)。
注意optional
就像我在评论中所说,我认为依靠<exclusions>
不是一个好主意。它通常意味着某些东西被打破。如果是造成它的人,那就特别糟糕了。