有没有一种方法可以全局排除Maven依赖项?

有没有一种方法可以全局排除Maven依赖项?,maven,maven-2,dependencies,pom.xml,Maven,Maven 2,Dependencies,Pom.xml,我试图找到一种“通用”的方法,不必将可传递依赖项从依赖它的所有依赖项中排除,就可以将其排除在外。例如,如果要排除slf4j,请执行以下操作: <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-jmx</artifactId> <version>3.3.2.GA</version> <ex

我试图找到一种“通用”的方法,不必将可传递依赖项从依赖它的所有依赖项中排除,就可以将其排除在外。例如,如果要排除slf4j,请执行以下操作:

  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jmx</artifactId>
    <version>3.3.2.GA</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>3.4.0.GA</version>
    <type>jar</type>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

org.hibernate
冬眠jmx
3.3.2.GA
org.slf4j
slf4j api
org.hibernate
休眠实体管理器
3.4.0.GA
罐子
org.slf4j
slf4j api
这部分是为了清理pom文件,部分是为了避免将来人们添加依赖于被排除的依赖项的依赖项,而忘记排除它的问题

有办法吗?

这有帮助吗

“假设我想将avalon框架从WAR中排除,我会将以下内容添加到我的项目POM中,范围为。这适用于所有可传递的依赖项,并允许您指定一次

<dependencies>
  <dependency>
      <artifactId>avalon-framework</artifactId>
      <groupId>avalon-framework</groupId>
      <version>4.1.3</version>
      <scope>provided</scope>
  </dependency>
</dependencies>

阿瓦隆框架
阿瓦隆框架
4.1.3
假如
这甚至可以在父POM中指定它时使用,这将防止项目必须在所有子POM中声明它。”

这有帮助吗

“假设我想将avalon框架从WAR中排除,我会将以下内容添加到我的项目POM中,范围为。这适用于所有可传递的依赖项,并允许您指定一次

<dependencies>
  <dependency>
      <artifactId>avalon-framework</artifactId>
      <groupId>avalon-framework</groupId>
      <version>4.1.3</version>
      <scope>provided</scope>
  </dependency>
</dependencies>

阿瓦隆框架
阿瓦隆框架
4.1.3
假如

这甚至可以在父POM中指定它时使用,这将防止项目必须在所有子POM中声明它。”

我创建了一个空jar并创建了此依赖项:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <scope>system</scope>
    <systemPath>${basedir}/src/lib/empty.jar</systemPath>
    <version>0</version>
</dependency>

公用记录
公用记录
系统
${basedir}/src/lib/empty.jar
0

它并不完美,因为从现在起,编译/测试路径中就有一个空jar。但这只是表面现象。

我创建了一个空罐子并创建了这个依赖项:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <scope>system</scope>
    <systemPath>${basedir}/src/lib/empty.jar</systemPath>
    <version>0</version>
</dependency>

公用记录
公用记录
系统
${basedir}/src/lib/empty.jar
0

它并不完美,因为从现在起,编译/测试路径中就有一个空jar。但这只是表面现象。

作为提醒,以下是Maven官方文档的答案:

为什么排除是基于每个依赖项而不是POM级别进行的

这样做主要是为了确保依赖关系图是可预测的,并防止继承效应排除不应排除的依赖关系。如果您使用了最后一种方法,并且不得不将其排除在外,那么您应该绝对确定哪些依赖项带来了不需要的可传递依赖项

如果想要使构建更加健壮,可以使用版本范围。这将确保没有更新版本的依赖项会干扰项目

<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>[1.4.2,)</version>
   <scope>provided</scope>
</dependency>

org.slf4j


  • 作为提醒,以下是Maven官方文档的答案:

    为什么排除是基于每个依赖项而不是POM级别进行的

    这样做主要是为了确保依赖关系图是可预测的,并防止继承效应排除不应排除的依赖关系。如果您使用了最后一种方法,并且不得不将其排除在外,那么您应该绝对确定哪些依赖项带来了不需要的可传递依赖项

    如果想要使构建更加健壮,可以使用版本范围。这将确保没有更新版本的依赖项会干扰项目

    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <version>[1.4.2,)</version>
       <scope>provided</scope>
    </dependency>
    
    
    org.slf4j
    
    
  • 要展开讨论:

    可以使用来确保排除依赖项。仍然需要手动排除它们,但是如果有人错误地将依赖项添加到其他地方,构建将失败

    <dependencies>
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-jmx</artifactId>
        <version>3.3.2.GA</version>
        <exclusions>
          <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
    </dependencies>
    
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>1.4.1</version>
        <executions>
          <execution>
            <goals>
              <goal>enforce</goal>
            </goals>
            <configuration>
              <rules>
                <bannedDependencies>
                  <excludes>
                    <exclude>org.slf4j:slf4j-api</exclude>
                  </excludes>
                </bannedDependencies>
              </rules>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
    
    
    org.hibernate
    

    要展开讨论:

    可以使用来确保排除依赖项。仍然需要手动排除它们,但是如果有人错误地将依赖项添加到其他地方,构建将失败

    <dependencies>
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-jmx</artifactId>
        <version>3.3.2.GA</version>
        <exclusions>
          <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
    </dependencies>
    
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>1.4.1</version>
        <executions>
          <execution>
            <goals>
              <goal>enforce</goal>
            </goals>
            <configuration>
              <rules>
                <bannedDependencies>
                  <excludes>
                    <exclude>org.slf4j:slf4j-api</exclude>
                  </excludes>
                </bannedDependencies>
              </rules>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
    
    
    org.hibernate
    

    这仍然只是一个局部攻击-依赖项不会在构建工件中结束,但在测试期间仍然可用。@TuukkaMustonen关于
    运行时
    范围而不是
    提供的
    范围如何?如果项目中的其他地方包括avalon framework 4.1.3+,会发生什么?在这里看到一个回答:我不再使用Maven,所以我无法测试其他答案,但我鼓励人们考虑它们,以防有一个不是局部黑客攻击。根据@TuukkaMustonen,这仍然只是一个部分攻击-依赖项不会最终出现在构建工件中,但在测试过程中仍然可用。@TuukkaMustonen如何处理
    运行时
    范围而不是提供的
    范围?如果项目中的其他地方包含avalon framework 4.1.3+,会发生什么?在这里看到一个回应:我不再使用Maven了,所以我不能测试其他答案,但是我鼓励大家考虑它们,以防其中一个不是部分黑客攻击,就像@ tukkauuStuunen不能解决这个问题一样,但是Maven Engor插件有一个如果不需要的依赖性潜入进来就会失败的构建。您仍然需要手动排除它们,尽管:-/这里有一个替代答案:不能解决问题,但是maven enforcer插件有一个漏洞,如果不需要的依赖项潜入,该漏洞将导致构建失败。您仍然需要手动排除它们,尽管:-/这里有一个备选答案:根据您的答案并阅读您提供的链接中的讨论,我意识到不需要的jar有时会进入胖jar,因为本地和服务器上使用的maven版本不同,所以打包逻辑可以添加完全不同的版本