Java 为什么maven war插件的行为不同于标准的maven依赖项解析机制

Java 为什么maven war插件的行为不同于标准的maven依赖项解析机制,java,eclipse,maven,Java,Eclipse,Maven,maven war插件的行为与标准maven依赖项解析机制不同,有什么原因吗? 我有一个war maven项目,它有一个依赖项: <dependency> <groupId>GroupA</groupId> <artifactId>DependencyA</artifactId> <exclusions> <exclusion>

maven war插件的行为与标准maven依赖项解析机制不同,有什么原因吗? 我有一个war maven项目,它有一个依赖项:

    <dependency>
        <groupId>GroupA</groupId>
        <artifactId>DependencyA</artifactId>
        <exclusions>
            <exclusion>
                <groupId>GroupB</groupId>
                <artifactId>DependencyB</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
我必须这样做,因为在我的项目中出现版本之间的冲突。 为什么会这样? 有没有其他方法可以做到这一点


更新

所以,我创建了一个测试用例,只是为了向您展示我的意思,如果我以前不够清楚的话。 相应的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/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>

4.0.0
GroupA
人工制品
战争
0.0.1-快照
Artfacta Maven Webapp
http://maven.apache.org
朱尼特
朱尼特
3.8.1
测试
B组
人工制品
战争
0.0.1-快照
C组
人工制品
人工制品

工件b

<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>

4.0.0
B组
人工制品
战争
0.0.1-快照
ArtifactB Maven Webapp
http://maven.apache.org
朱尼特
朱尼特
3.8.1
测试
C组
人工制品
0.0.1-快照
人工制品

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>

4.0.0
C组
人工制品
0.0.1-快照
罐子
人工神经
http://maven.apache.org
UTF-8
朱尼特
朱尼特
3.8.1
测试

在Eclipse的依赖层次结构中,我没有看到依赖工件C。

在构建工件和解压缩战争时,我得到:

如您所见,可传递依赖项包含在WEB-INF/lib中的.war中。 我希望这一点现在更清楚

要添加的其他一些详细信息:

  • 我在eclipse给maven打电话
  • maven war插件版本2.1.1,也测试了2.5
  • 嵌入Eclipse的Maven 3.0.4版

  • 我也注意到了
    的奇怪行为。我最好的建议是把它放在战争项目(项目A)中

    然后在实际需要的地方显式添加ArtifactC和ArtifactB依赖项(即在其他地方部署B)

    注意
    可选的


    正如我在评论中所说,我认为依赖
    不是一个好主意。它通常意味着有东西坏了。如果您的应用程序是导致它的原因,那么这尤其糟糕。

    问题不在于war插件以不同的方式处理依赖项排除,而在于它专门处理
    war
    的依赖项。它从这些内容中创建了一个新的应用程序,这意味着它将整个战争的内容放在首位,并将项目web资源放在首位。war依赖项实际上没有可传递的依赖项,它已经包含了所有jar文件


    如果您真的打算使用war覆盖,那么使用
    packagingExcludes
    是正确的解决方案。如果您想要依赖工件B中的类,那么您应该修改pom,使其创建一个单独的工件(使用),并依赖于这个
    工件。然后,排除可传递依赖项应与排除任何其他jar依赖项一样有效。

    可传递依赖项CYB是否偶然被另一个依赖项(不是a)包含?您可能需要在多个位置排除它。请添加完整的pom。哪个Maven版本?你使用哪个版本的maven war插件?你怎么称呼maven的?从命令行?如您所述,为
    ArtifactB
    pom.xml中的依赖性
    ArtifactC
    提供的
    范围将起作用(经测试)对于工件的构建,但我非常确定,如果您需要在某个地方单独部署它,这将破坏
    ArtifactB的部署。我甚至不确定它是否能工作,所以不太可能每个人都将ArtifactB部署到另一个项目中(即依赖它,就好像它是一个jar)。此外,对于DEP错误的项目,排除更像是一种黑客行为。意思是有东西坏了<代码>提供
    另一方面意味着您已经部署了代码或类似代码的东西(比如servlet jar)。对不起,我的意思是将提供的放在工件上。这可能是混淆的地方(我甚至在上一篇评论中也混淆了自己)。是的,
    提供的
    是您所说的“已经部署了代码或类似代码的东西(如servlet jars)”,但在这种特定情况下被用作黑客,因为将依赖项
    ArtifactC
    设置为提供的
    ArtifactC
    会使其在运行时不可用,因为您希望容器之类的其他人提供它。但实际上没有其他人提供这个特定的依赖项,而您有另一个不同版本的依赖项。因此,在我的情况下,这是行不通的,因为我希望能够单独部署
    ArtifactB
    (例如
    ArtifactA
    是GUI,而
    ArtifactB
    是RESTAPI),您是否尝试过
    可选
    (我的上次编辑)?如果没有提供,那么它听起来像是可选的。我只是不明白为什么ArtifactA实际上不需要ArtifactC。如果它不需要,听起来像是一个可选的依赖项。不管是那样还是ArtifactB都需要重构成更多的工件。谢谢你提供的信息,这让我对真正发生的事情有了更多的了解。我正在使用的
    packagingExcludes
    是我的最佳选择,因为我依赖于其他东西,不仅jar依赖项和
    attachClasses
    解决方案基本上将排除
    WEB-INF
    目录
    <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>
    
    <dependency>
        <groupId>GroupC</groupId>
        <artifactId>ArtifactC</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <scope>provided</scope>
    </dependency>
    
    <dependency>
        <groupId>GroupC</groupId>
        <artifactId>ArtifactC</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <optional>true</optional>
    </dependency>