无论如何排除从父POMinheritance的工件?

可以通过在<dependency>声明一个<exclusions>元素来排除依赖关系中的工件。但是在这种情况下,需要排除从父项目inheritance的工件。 正在讨论的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.jar ,而ALL-DEPS依赖于同一个库的另一个版本。 由于执行环境中存在来自ALL-DEPS mail.jar ,虽然没有被导出,但是与父节点上存在的mail.jar发生冲突,其范围为compile

一个解决scheme可能是从父POM中删除mail.jar,但是大部分inheritancebase的项目都需要它(因为是log4j的一个transitive依赖项)。 所以我想要做的就是简单地将父库从子项目中排除 ,因为如果base是依赖关系而不是父项目 ,那么可以这样做:

 ... <dependency> <artifactId>base</artifactId> <groupId>es.uniovi.innova</groupId> <version>1.0.0</version> <type>pom<type> <exclusions> <exclusion> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> </exclusion> </exclusions> </dependency> ... 

一些想法:

  1. 也许你可以在这种情况下不能inheritance父类(并且声明一个依赖于base的排除)。 如果你在父Pom中有很多东西,那就不方便。

  2. 另一件要testing的东西是在父pom中的dependencyManagement下用ALL-DEPS所需的版本声明mail工件以强制收敛(尽pipe我不确定这将解决范围问题)。

     <dependencyManagement> <dependencies> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>???</version><!-- put the "right" version here --> </dependency> </dependencies> </dependencyManagement> 
  3. 或者,如果您不使用依赖于它的function,则可以从log4j中排除mail依赖关系(这是我将要做的):

     <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> 
  4. 或者你可以恢复到log4j的版本1.2.14,而不是1.2.4的异端版本(为什么他们不把上面的依赖关系标记为可选的 !)。

您可以按照Sonatypes 最佳实践的说明将您的依赖项与包装包在不同的项目中分组:

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

您的子项目像以前一样inheritance了这个父项目。 但现在,依赖dependencyManagement块中的子项目中可以排除邮件依赖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> 

你有没有试过显式声明你想要的mail.jar的版本? Maven的依赖解决scheme应该使用它来解决所有其他版本的依赖关系。

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

最好的办法是使你不总是希望inheritance传递的依赖。

您可以通过在提供的范围内在父pom中标记它们来做到这一点。

如果您仍然希望父级pipe理这些代码的版本,则可以使用<dependencyManagement>标记设置所需的版本,而不显式inheritance它们,或将该inheritance传递给子代。

第一篇文章…希望这是值得的东西!

当你调用一个包但不想要一些依赖的时候,你可以做这样的事情(在这种情况下,我不想添加旧的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很新,所以它可能不是最佳的。