maven - maven 着色是如何工作的?
问题描述
在这篇问答文章中,我们将尝试回答以下问题 -
- 什么是maven中的阴影?
- 是
maven-shade-plugin
什么,用途是什么? - 如何配置
maven-shade-plugin
实现遮光?
解决方案
1. 什么是阴影?
在 的上下文中maven
,着色是一个过程,您可以通过该过程更改项目所依赖的某些依赖项的包名称。这样做的主要原因之一是解决依赖版本冲突。
考虑一下 - 您的项目依赖于特定版本的依赖项,例如com.fasterxml.jackson:jackson-databind
- v2.9.10
。您构建了一个 uber jar,将依赖项打包到服务的工件中。现在,假设您运行服务的主机提供了一个运行时环境,该环境提供com.fasterxml.jackson:jackson-databind
- v2.6.7
。
我们有问题。在类路径上使用同一个库的两个版本,我们将遇到运行时错误和不可预知的行为。例如,您的代码调用了of 中的FAIL_ON_TRAILING_TOKENS
字段,但该字段在 v2.9.10
com.fasterxml.jackson:jackson-databind
com.fasterxml.jackson:jackson-databind
-v2.6.7
中不存在。所以本质上,我们有两个版本的com.fasterxml.jackson.databind.DeserializationFeature.java
类。运行时不知道要拉哪一个,在这种情况下,您很可能会在运行时看到以下错误 -
java.lang.NoSuchFieldError: FAIL_ON_TRAILING_TOKENS
那不好。在生产环境中运行代码时,您希望它是可预测的并且在您的控制之下。
那么,我们如何解决这个问题呢?阴影来拯救。通过阴影我们改变了类的“完全限定名” ——所以我们将有两个不同DeserializationFeature.java
的类,而不是有两个版本的类——com.fasterxml.jackson.databing.DeserializationFeature.java
com.fasterxml.jackson.databind.DeserializationFeature.java
shaded-base.com.fasterxml.jackson.databind.DeserializationFeature.java
将应用于工件及其中的所有类shaded-base
的前缀在哪里。让我们看看它实际上是如何完成的。maven-shade-plugin
com.fasterxml.jackson:jackson-databind:2.9.10
2.Maven-Shade-Plugin
现在我们已经简单地熟悉了什么是着色以及何时使用它,让我们深入了解一下maven-shade-plugin
它本身。
2.a) 使用构建一个 uber jarmaven-shade-plugin
除了着色之外,maven-shade-plugin
还可以用来构建一个超级罐子,也称为“胖”罐子。uber jar 是一个 jar,您可以在其中打包项目所需的几乎所有依赖项。
让我们从一个例子开始。检查项目<dependencies>
所需lake-tahoe
。
通过使用maven-shade-plugin
我们将依赖项打包到lake-tahoe
项目的最终工件中。你可以自己做。只需克隆存储库,然后运行以下命令 -
➜ lake-tahoe (master) mvn clean install
这将lake-tahoe-<version>-SNAPSHOT.jar
在target/
目录中创建。现在,让我们检查jackson
文件是否“打包”在该工件中;出于本文的目的,我们将检查该DeserializationFeature.java
文件。
➜ lake-tahoe (master) jar tf target/lake-tahoe-1.0.2-SNAPSHOT.jar | grep DeserializationFeature
com/fasterxml/jackson/databind/DeserializationFeature.class
是的。我们看到maven-shade-plugin
将项目的依赖包打包在 uber jar 中。
2.b) 对依赖项进行着色。
我们可以使用<relocations>
插件的元素来遮蔽或“重新打包”依赖项。检查truckee-river
项目的pom.xml
配置,看看我们是如何实现的。克隆 repo 并运行以下命令 -
truckee-river (master) mvn clean install
让我们检查一下truckee-river
uber jar 的内容。
➜ truckee-river (master) ✗ jar tf target/truckee-river-1.0.2-SNAPSHOT.jar | grep DeserializationFeature
com/water/bodies/fasterxml/jackson/databind/DeserializationFeature.class
如您所见,中的所有类com.fasterxml.jackson
都已“重新定位”到com.water.bodies.fasterxml.jackson
. 所以,这就是阴影。
2.c) 使用带阴影的同一库的两个版本
让我们来看看这个lake-pyramid
项目。它拉入v2.6.7
图书馆com.fasterxml.jackson:jackson-databind
,也拉入truckee-river
项目。正如我们在 #2.b 部分中看到的那样,truckee-river
拉入lake-tahoe
工件,然后v2.9.10
将com.fasterxml.jackson:jackson-databind
. 然而,truckee-river
项目遮蔽com.fasterxml.jackson
并重新定位它,实际上创建了一个新的“完全合格的类”。
克隆lake-pyramid
,您可以自己看到阴影和v2.6.7
版本都打包在lake-pyramid
的最终工件中。
➜ lake-pyramid (master) mvn clean install
// creates the `lake-pyramid-1.0.0-SNAPSHOT.jar`
(base) ➜ lake-pyramid (master) jar tf target/lake-pyramid-1.0.0-SNAPSHOT.jar | grep DeserializationFeature
com/water/bodies/fasterxml/jackson/databind/DeserializationFeature.class
com/fasterxml/jackson/databind/DeserializationFeature.class
所以,差不多就是这样。自己在本地尝试这些示例,您会感觉更舒服。
推荐阅读
- python - TensorFlow 异常:模块 'tensorflow.tools.api.generator.api.math' 没有属性 'log'
- apache-flex - Flex mxmlc ant 任务给出 java.lang.OutOfMemoryError: Java heap space
- scala - 如何构建多个 Spark 数据帧并并行运行?
- microsoft-graph-api - 如何将 onedrive 文件共享给组织外的人员
- go - 如何使用gorm创建到mysql的ssl连接?
- angularjs - 使用 angularjs 显示 API 内容
- linux - rc.local 的环境
- python - 无法用尽加载更多按钮来揭开所有头条新闻
- c - 拆分字符串并使用索引来调用所需的元素
- swift - 与 collectionView.reloadItems[at: [indexPath]] 重叠标签值