我发现有人在 pom.xml 中使用了 maven-shade-plugin。我以前从未使用过 maven-shade-plugin(我是 Maven n00b),所以我试图了解使用它的原因以及它的作用。
我查看了 Maven 文档,但是我无法理解这个声明:
这个插件提供了将工件打包在 uber-jar 中的能力,包括它的依赖项和遮蔽 - 即重命名 - 一些依赖项的包。
页面上的文档似乎对新手不太友好。
什么是“超级罐”?为什么有人想做一个?重命名依赖项的包有什么意义?我尝试浏览 maven-shade-plugin apache 页面上的示例,例如“为 Uber Jar 选择内容”,但我仍然无法理解“着色”正在完成什么。
任何指向说明性示例/用例的指针(解释为什么在这种情况下需要阴影 - 它解决了什么问题)将不胜感激。最后,我应该什么时候使用 maven-shade-plugin?
原文由 nonbeing 发布,翻译遵循 CC BY-SA 4.0 许可协议
简而言之,Uber JAR 是一个包含所有内容的 JAR。
通常在 Maven 中,我们依赖于依赖管理。工件仅包含其自身的类/资源。 Maven 将负责根据项目的构建时间找出项目的所有工件(JAR 等)。
uber-jar 是一种获取所有依赖项的东西,并提取依赖项的内容并将它们与项目本身的类/资源一起放在一个大 JAR 中。通过拥有这样一个 uber-jar,执行起来很容易,因为您只需要一个大 JAR 而不是大量的小 JAR 来运行您的应用程序。在某些情况下,它还简化了分发。
附带说明:避免使用 uber-jar 作为 Maven 依赖项,因为它会破坏 Maven 的依赖项解析功能。通常我们只为实际部署或手动分发的最终工件创建一个 uber-jar,而不是用于放入 Maven 存储库。
更新:我刚刚发现我还没有回答问题的一部分:“重命名依赖项的包有什么意义?”。以下是一些简短的更新,希望能帮助有类似问题的人。
创建一个易于部署的 uber-jar 是 shade 插件的一个用例。还有其他涉及包重命名的常见用例。
例如,我正在开发
Foo
库,它依赖于Bar
库的特定版本(例如 1.0)。假设我不能使用Bar
lib 的其他版本(因为 API 更改或其他技术问题等)。 If I simply declareBar:1.0
asFoo
’s dependency in Maven, it is possible to fall into a problem: AQux
project is depending onFoo
, and alsoBar:2.0
(and it cannot useBar:1.0
becauseQux
needs to use new feature inBar:2.0
). Here is the dilemma: shouldQux
useBar:1.0
(whichQux
’s code will not work) orBar:2.0
(whichFoo
的代码不起作用)?为了解决这个问题,
Foo
的开发者可以选择使用shade插件重命名Bar
的用法,这样Bar:1.0
jar在Foo
jar 中,嵌入的Bar
classes 的包从com.bar
更改为com.foo.bar
。 By doing so,Qux
can safely depends onBar:2.0
because nowFoo
is no longer depending onBar
, and it is using its own “更改”的副本Bar
位于另一个包中。