Java Maven-shade-plugin、uber-jar 和重叠类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19987080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:05:05  来源:igfitidea点击:

Maven-shade-plugin, uber-jar and overlapping classes

javamavendependenciesoverlap

提问by user2148736

I would like to use Maven-shade-plugin to create uber-jar. But when I call mvn packagecommand Maven reports that there are some overlapping classes. I am attaching all problematic overlapps, some of them are caused because older and new verion of a library (Log4J), but some of them seems to have the same classes - e.g. javax.mail and mailapi/smtp/imap et cetera.

我想使用 Maven-shade-plugin 创建 uber-jar。但是当我调用mvn package命令时,Maven 报告说有一些重叠的类。我附上了所有有问题的重叠,其中一些是由于库 (Log4J) 的旧版本和新版本引起的,但其中一些似乎具有相同的类 - 例如 javax.mail 和 mailapi/smtp/imap 等等。

What is the best to do in this situation? Is there some key how to decide which overlapping is safe to ignore a which needs to be correct?

在这种情况下最好做什么?是否有一些关键如何确定哪些重叠可以安全忽略哪些需要正确?

 - mailapi-1.4.3.jar, javax.mail-1.5.0.jar define 166 overlappping classes
 - spring-2.5.6.SEC03.jar, spring-tx-3.1.4.RELEASE.jar define 176 overlappping classes:
 - spring-beans-3.1.4.RELEASE.jar, spring-2.5.6.SEC03.jar define 283 overlappping classes:
 - slf4j-log4j12-1.7.5.jar, slf4j-impl-2.0-beta2.jar define 3 overlappping classes:
 - spring-2.5.6.SEC03.jar, spring-context-support-3.1.4.RELEASE.jar define 55 overlappping classes:
 - aopalliance-1.0.jar, spring-2.5.6.SEC03.jar define 9 overlappping classes:
 - imap-1.5.0.jar, javax.mail-1.5.0.jar define 87 overlappping classes:
 - commons-logging-api-1.1.jar, commons-logging-1.1.3.jar define 19 overlappping classes:
 - spring-2.5.6.SEC03.jar, spring-core-3.1.4.RELEASE.jar define 161 overlappping classes:
 - spring-2.5.6.SEC03.jar, spring-context-3.1.4.RELEASE.jar define 326 overlappping classes: 
 - log4j12-api-2.0-beta3.jar, log4j-1.2.17.jar define 23 overlappping classes: 
 - spring-aop-3.1.4.RELEASE.jar, spring-2.5.6.SEC03.jar define 237 overlappping classes:
 - spring-jdbc-3.1.4.RELEASE.jar, spring-2.5.6.SEC03.jar define 239 overlappping classes:
 - quartz-1.8.6.jar, quartz-jobs-2.2.1.jar define 15 overlappping classes:
 - smtp-1.5.0.jar, javax.mail-1.5.0.jar define 17 overlappping classes: 
 - spring-asm-3.1.4.RELEASE.jar, spring-2.5.6.SEC03.jar define 31 overlappping classes: 

EDIT:this application "A" uses as a Maven dependency my another Java application - I'll call this app "B". This B application uses javax.mail ver 1.5.1. This library uses the first application too. But when I call mvn package command, Maven notices that javax.mail-api-1.5.1.jar, javax.mail-1.5.1.jar define 135 overlappping classes.

编辑:此应用程序“A”用作我的另一个 Java 应用程序的 Maven 依赖项 - 我将此应用程序称为“B”。此 B 应用程序使用 javax.mail 版本 1.5.1。这个库也使用第一个应用程序。但是当我调用 mvn package 命令时,Maven 注意到javax.mail-api-1.5.1.jar, javax.mail-1.5.1.jar define 135 overlappping classes.

Is this problem and if so, how to solve it or can I ignore it?

这是问题吗?如果是,如何解决,或者我可以忽略它吗?

采纳答案by stusrob

The first thing to do is remove as many of the obvious causes of overlapping classes as you can. For instance:

首先要做的是尽可能多地消除重叠类的明显原因。例如:

  • You have dependencies on both spring 2.5.6 and spring 3.1.4, which will give you more problems than just in the shade plugin. Set up your module dependencies so you have just one version of spring. Use dependency exclusions if you have to (say you have transitive dependencies that you do not control).
  • Once the dependency version clashes are fixed, you can also configure which jars go into the uber-jar with the shade plugin configuration, as described at http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html
  • Some of the jars probably contain all of the classes from their overlapping jars.
    • I suspect that commons-logging-1.1.3.jar has a superset of the classes declared in commons-logging-api-1.1.jar. If this is the case, you can exclude the api jar.
    • In response to the edited question, javax.mail-1.5.1.jar contains a superset of the classes in javax.mail-api-1.5.1.jar. Since these are clearly the same version and the overlapping classes should be identical, it will do no harm to build the shaded jar with the overlapping classes (it will take the classes from whichever jar it processes last). However, the build will be tidier and slightly faster if you exclude the api jar.
  • 您对 spring 2.5.6 和 spring 3.1.4 都有依赖性,这会给您带来比仅在 shade 插件中更多的问题。设置您的模块依赖项,以便您只有一个版本的 spring。如果必须,请使用依赖项排除(假设您有无法控制的传递依赖项)。
  • 修复依赖版本冲突后,您还可以使用 shade 插件配置配置哪些 jar 进入 uber-jar,如http://maven.apache.org/plugins/maven-shade-plugin/examples/includes 所述-excludes.html
  • 一些罐子可能包含它们重叠罐子中的所有类。
    • 我怀疑 commons-logging-1.1.3.jar 有一个在 commons-logging-api-1.1.jar 中声明的类的超集。如果是这种情况,您可以排除 api jar。
    • 作为对编辑问题的回应,javax.mail-1.5.1.jar 包含 javax.mail-api-1.5.1.jar 中类的超集。由于这些显然是相同的版本并且重叠的类应该是相同的,因此使用重叠的类构建着色的 jar 没有坏处(它将从它最后处理的任何 jar 中获取类)。但是,如果排除 api jar,构建会更整洁,速度也会稍微快一些。

It's unlikely that you will need to retain conflicting versions of the classes in the shaded jar. If you do, the shade plugin also allows the relocation of classes, as described at http://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html

您不太可能需要在阴影 jar 中保留类的冲突版本。如果这样做,shade 插件还允许重新定位类,如http://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html 所述

回答by Rohit Sardesai

I found the maven dependency tree pluginvery useful to find out from where is the nested dependency coming from , and then add an exclusion for it.

我发现maven 依赖树插件非常有用,可以找出嵌套依赖的来源,然后为它添加排除项。

$ **mvn dependency:tree -Dverbose -Dincludes=aopalliance**
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building petshop cli 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ cli ---
[INFO] com.sample.petshop:cli:jar:1.0
[INFO] \- **org.springframework:spring-context**:jar:4.1.3.RELEASE:compile
[INFO]    \- org.springframework:spring-aop:jar:4.1.3.RELEASE:compile
[INFO]       \- **aopalliance:aopalliance**:jar:1.0:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.865s
[INFO] Finished at: Fri May 08 15:12:01 IST 2015
[INFO] Final Memory: 14M/223M
[INFO] ------------------------------------------------------------------------

The aopalliance jar is being referenced from spring-context-support which indicates that we could possibly exclude it.

aopalliance jar 是从 spring-context-support 引用的,这表明我们可以排除它。

回答by radistao

This question duplicates this one, where you could find more examples.

这个问题重复这一个,在那里你可以找到更多的例子。

But in case you are sure you don't have overlapping dependencies (like i had), cleaning project could help. See this answer for more details

但是,如果您确定没有重叠的依赖项(就像我有的那样),cleaning project 可能会有所帮助。有关更多详细信息,请参阅此答案