反正有没有排除从父POM继承的工件?

时间:2010-04-21 09:40:37

标签: java maven-2 pom.xml

可以通过在<exclusions>内声明<dependency>元素来排除依赖项中的工件。但在这种情况下,需要排除从父项目继承的工件。正在讨论的POM的摘录如下:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>test</groupId>
  <artifactId>jruby</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
    </parent>

    <dependencies>      
        <dependency>
            <groupId>com.liferay.portal</groupId>
            <artifactId>ALL-DEPS</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>

base工件取决于javax.mail:mail-1.4.jarALL-DEPS取决于同一个库的其他版本。由于执行环境中存在来自mail.jar的{​​{1}},尽管未导出,但与父项上存在的ALL-DEPS发生冲突,其范围为mail.jar

解决方案可能是从父POM中删除mail.jar,但是大多数继承base的项目都需要它(因为它是log4j的转换依赖项)。所以我想做的是简单地从子项目中排除父项库,因为如果compile是依赖项而不是父项pom,可以这样做:

base

10 个答案:

答案 0 :(得分:40)

一些想法:

  1. 在这种情况下,你可能根本就没有从父级继承(并在排除的情况下声明对base的依赖)。如果父母pom中有很多东西,那就不方便了。

  2. 要测试的另一件事是使用父pom中mailALL-DEPS所需的版本声明dependencyManagement工件,以强制收敛(尽管我'我不确定这会解决范围问题。)

  3. <dependencyManagement>
      <dependencies>
        <dependency>    
          <groupId>javax.mail</groupId>
          <artifactId>mail</artifactId>
          <version>???</version><!-- put the "right" version here -->
        </dependency>
      </dependencies>
    </dependencyManagement>
    
    1. 如果你没有使用依赖它的功能,你可以从log4j中排除mail依赖项(这就是我要做的):
    2. <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.15</version>
        <scope>provided</scope>
        <exclusions>
          <exclusion>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
          </exclusion>
          <exclusion>
            <groupId>javax.jms</groupId>
            <artifactId>jms</artifactId>
          </exclusion>
          <exclusion>
            <groupId>com.sun.jdmk</groupId>
            <artifactId>jmxtools</artifactId>
          </exclusion>
          <exclusion>
            <groupId>com.sun.jmx</groupId>
            <artifactId>jmxri</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      
      1. 或者您可以恢复到log4j的版本1.2.14而不是异端的1.2.15版本(为什么他们没有将上述依赖项标记为可选?!)。

答案 1 :(得分:21)

如Sonatypes Best Practices所述,您可以使用打包pom在不同项目中对依赖项进行分组:

<project>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>base-dependencies</artifactId>
    <groupId>es.uniovi.innova</groupId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <dependencies>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>
</project>

并从您的父pom中引用它们(观察依赖项<type>pom</type>):

<project>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>base</artifactId>
    <groupId>es.uniovi.innova</groupId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <dependencies>
        <dependency>
            <artifactId>base-dependencies</artifactId>
            <groupId>es.uniovi.innova</groupId>
            <version>1.0.0</version>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>

你的子项目像以前一样继承了这个父pom。但现在,可以在dependencyManagement块中的子项目中排除邮件依赖项:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>test</groupId>
    <artifactId>jruby</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <artifactId>base-dependencies</artifactId>
                <groupId>es.uniovi.innova</groupId>
                <version>1.0.0</version>
                <exclusions>
                    <exclusion>
                        <groupId>javax.mail</groupId>
                        <artifactId>mail</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

答案 2 :(得分:6)

您是否尝试过明确声明所需的mail.jar版本? Maven的依赖性解析应该使用它来解决所有其他版本的依赖性解析。

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>test</groupId>
  <artifactId>jruby</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
    </parent>
    <dependencies>          
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>VERSION-#</version>
            <scope>provided</scope>
        </dependency> 
        <dependency>
            <groupId>com.liferay.portal</groupId>
            <artifactId>ALL-DEPS</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>

答案 3 :(得分:5)

不要使用父pom

这可能听起来很极端,但同样的方式“继承地狱”是一些人背弃面向对象编程的原因,或者外科医生通过冠状动脉搭桥手术让你活着的同样方式:删除有问题的<parent>阻止和copy and paste您需要的<dependencies>

应该忽略将poms分成父母和孩子以“重用”和“避免冗余”的假设,你应该首先满足你的直接需求。冗余有其优点 - 即外部并发症的独立性。

如果您生成有效的pom(eclipse提供它,但您可以从命令行生成它),这比听起来更容易。

实施例

我想使用logback,但我的父pom使用log4j,我不想继续将其他孩子对log4j的依赖推到他们自己的pom.xml文件中以便我的通畅。

你可以从父母那里得到很多,但有时你的父母不知道什么对你有好处。

答案 4 :(得分:4)

使用指向空jar的scope系统重新定义依赖项(在子pom中):

<dependency>
    <groupId>dependency.coming</groupId>
    <artifactId>from.parent</artifactId>
    <version>0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/empty.jar</systemPath>
</dependency>

jar只能包含一个空文件:

touch empty.txt
jar cvf empty.txt

答案 5 :(得分:2)

最好的办法是让你不总是想要继承不敏感的依赖关系。

您可以通过在提供范围的父pom中标记它们来实现此目的。

如果您仍希望父级管理这些deps的版本,则可以使用<dependencyManagement>标记设置所需的版本,而无需显式继承它们,或将该继承传递给子级。

答案 6 :(得分:1)

当你调用一个包但不想要它的某些依赖项时你可以做这样的事情(在这种情况下我不想添加旧的log4j,因为我需要使用更新的一个):

<dependency>
  <groupId>package</groupId>
  <artifactId>package-pk</artifactId>
  <version>${package-pk.version}</version>

  <exclusions>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<!-- LOG4J -->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.5</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-api</artifactId>
  <version>2.5</version>
</dependency>

这对我有用......但我对java / maven很新,所以它可能不是最佳的。

答案 7 :(得分:1)

我真的需要做这件肮脏的事...这是

我用范围test重新定义了那些依赖项。范围provided对我不起作用。

我们使用spring Boot插件来构建胖子。我们有 common 模块,该模块定义了常见的库,例如Springfox swagger-2。我的超级服务需要具有父级 common (它不想这样做,但公司必须遵守!)

所以我的父母或下议院有pom。

<dependencyManagement>

    <!- I do not need Springfox in one child but in others ->

    <dependencies>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-bean-validators</artifactId>
            <version>${swagger.version}</version>
        </dependency>

       <!- All services need them ->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${apache.poi.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

还有我的超级服务 pom。

<name>super-service</name>
<parent>
    <groupId>com.company</groupId>
    <artifactId>common</artifactId>
    <version>1</version>
</parent>

<dependencies>

    <!- I don't need them ->

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-bean-validators</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-core</artifactId>
        <version>2.8.0</version>
        <scope>test</scope>
    </dependency>

    <!- Required dependencies ->

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
     <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
    </dependency>
</dependencies>

这是最终的脂肪假象的大小

82.3 MB (86,351,753 bytes) - redefined dependency with scope test
86.1 MB (90,335,466 bytes) - redefined dependency with scope provided
86.1 MB (90,335,489 bytes) - without exclusion

这个答案也值得一提-我想这么做,但是我很懒... https://stackoverflow.com/a/48103554/4587961

答案 8 :(得分:0)

我们可以将父pom添加为pom类型的依赖项,并对此进行排除。因为无论如何,父pom已下载。这对我有用

<dependency>
  <groupId>com.abc.boot</groupId>
  <artifactId>abc-boot-starter-parent</artifactId>
  <version>2.1.5.RELEASE</version>
  <type>pom</type>
  <exclusions>
    <exclusion>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
    </exclusion>
  </exclusions>   
</dependency>

答案 9 :(得分:0)

在子 pom.xml 中重复父项的依赖项并在那里插入排除项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>com.vaadin.external.google</groupId>
            <artifactId>android-json</artifactId>
        </exclusion>
    </exclusions>
</dependency>