2016-02-10 313 views
4

我使用maven-shade-plugin来创建一个可执行的jar包含我的项目的所有依赖关系。有时候,这些依赖关系会导致自己的依赖关系与其他库的依赖关系发生冲突,maven-shade-plugin会警告我不确定哪个版本包含在uber jar中。使用maven-shade-plugin时,我应该如何处理依赖冲突?

[WARNING] maven-shade-plugin has detected that some .class files 
[WARNING] are present in two or more JARs. When this happens, only 
[WARNING] one single version of the class is copied in the uberjar. 
[WARNING] Usually this is not harmful and you can skeep these 
[WARNING] warnings, otherwise try to manually exclude artifacts 
[WARNING] based on mvn dependency:tree -Ddetail=true and the above 
[WARNING] output 

一般来说,我这个预警反应是使用依赖性声明中的<exclusions>元素在我的POM文件从我的项目中删除有问题的相关性:当我做这个

<!-- Amazon ElastiCache Client --> 
<dependency> 
    <groupId>com.amazonaws</groupId> 
    <artifactId>elasticache-java-cluster-client</artifactId> 
    <version>1.0.61.0</version> 
    <exclusions> 
     <!-- this junit dependency clashes with our test-scoped one and causes integration tests to fail to run --> 
     <exclusion> 
      <groupId>junit</groupId> 
      <artifactId>junit-dep</artifactId> 
     </exclusion> 
     <!-- this dependency brings in two versions of cglib that clash with one another --> 
     <exclusion> 
      <groupId>jmock</groupId> 
      <artifactId>jmock-cglib</artifactId> 
     </exclusion> 
     <!-- newer versions of these dependencies come with dropwizard-core --> 
     <exclusion> 
      <groupId>log4j</groupId> 
      <artifactId>log4j</artifactId> 
     </exclusion> 
     <exclusion> 
      <groupId>commons-logging</groupId> 
      <artifactId>commons-logging</artifactId> 
     </exclusion> 
     </exclusions> 
</dependency> 

,我使用mvn dependency:tree来确保我排除了较低版本的违规依赖,希望最新版本是最成熟和无bug的版本。

情况下,像上面说的一个结了很多排除提高对这种做法两个问题:

  1. 在上面的例子,为什么我必须手动排除JUnit和JMock的?这两个依赖在the elasticache-java-cluster-client pom.xml中被标记为<scope>test</scope>,所以我希望它们不会包含在我从maven获得的jar中。
  2. 尽管我一直在服用更新版本的依赖项的做法似乎已经奏效,但恐怕这些日子里我会打破某些东西。有没有更好的方法来确定保留哪个版本的依赖关系?
+0

嗨,你能提供你使用的插件版本。一般来说,它不会添加标记为范围测试的库。有没有其他的一些情况在您的pom中没有标记为范围测试?依赖项部分的排除机制,用于解决您的依赖关系而不是阴影插件的Maven反应器。因此,通过在依赖项中定义排除项,您只需向Maven指明要考虑哪些依赖项,哪些不依赖项。另一方面,如果您想控制(过滤)插件的依赖关系和包含,您需要在插件上提供配置 – javapapo

+0

请参见[这里](https://maven.apache.org/plugins/maven-shade -plugin/examples/includes-excludes.html#)为阴影插件配置 – javapapo

+0

我使用maven-shade-plugin的2.3版本。 我熟悉maven-shade-plugin配置,并且已经按照链接页面上的建议进行了设置。 我的问题是关于人们在选择要添加哪些排除项时通常会采取的策略,而不是如何首先添加排除项。 – MusikPolice

回答

2

您是否尝试过将maven-enforcer-pluginDependencyConvergence rule相加?这与我的阴影插件结合使用效果很好。它会告诉你哪些工件引入了相同类的不同版本。它允许我找出我必须排除的东西。

 <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-enforcer-plugin</artifactId> 
      <executions> 
       <execution> 
        <id>enforce</id> 
        <configuration> 
         <rules> 
          <DependencyConvergence/> 
         </rules> 
        </configuration> 
        <goals> 
         <goal>enforce</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 
+0

坚实的建议,但它可能对现实世界太严格。例如,我的项目依赖于'ru.vyarus:dropwizard-guicey:3.1.1',它依次具有依赖关系收敛错误 - 依赖关系之一依次取决于'com.google.inject:guice:3.0',而另外两个依赖于'com.google.inject:guice:4.0'。 Maven的排除不允许我指定要包含哪些版本的东西,所以我不知道如何解决这个问题。 – MusikPolice