我在项目中使用了maven shade插件来重定位一个包下的所有依赖jar类,例如org.shade。*
当我尝试在其他应用程序中使用该阴影jar作为maven依赖时,它会拉动依赖jar。
我的期望是当uber / shaded jar包含为maven依赖时,它不应该拉任何其他依赖类jar,因为已经在shaded jar中重新打包这些类。
答案 0 :(得分:2)
在生成uber jar的 源项目 上的pom.xml声明了传递性依赖项(如果将其作为依赖项包含在 external中)项目 ,那么Maven将尝试获取这些文件(即使这些文件已包含在uber jar中)。
我共享一个解决方案,让您避免像@A_DiMatteo在其解决方案中所解释的那样,将所有传递性依赖项(包括它)明确排除在外部项目中(我也同意他避免使用uber jar作为依赖项(如果出于某种原因并非绝对必要))。因此,您应该能够在不使用 exclusions 元素的情况下包括uber jar依赖项,如下所示:
<dependency>
<groupId>com.sample</groupId>
<artifactId>something-uber</artifactId>
<version>some-version</version>
</dependency>
前提:我的目标是在存储库中同时提供 uber (没有在pom上声明传递依赖项)和 thin 罐子。因此,我的解决方案“ A”是基于这种情况的,目前存在限制,即将有阴影的jar上载到存储库2次。
- 仅提供 uber jar,请参见下面的“ B”解决方案
- 有关“ A”限制的可能解决方案,请参阅最后的更新部分
1-在您的 源项目 上,在事物模块pom.xml上配置以下 maven-shade-plugin 如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>something-uber-${project.version}</finalName>
</configuration>
</execution>
</executions>
</plugin>
然后使用 build-helper-maven-plugin 插件将新工件与模块上的“超级”分类器相连:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>
${project.build.directory}/something-uber-${project.version}.jar
</file>
<classifier>uber</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
这将作为Maven安装阶段的结果,在 target / 目录上生成以下两个jar:
40K something-0.1.0.jar
7M something-uber-0.1.0.jar
警告::然后执行maven部署阶段两个jar都将上传到存储库中!!此处的目标应该是仅上传 thin jar >跳过部署有阴影的jar 以便将其保留为本地工件(有关可能的修复,请参见最后的 UPDATE 部分)
2-然后在您的源项目上创建另一个名为 something-uber 的模块,并添加以下依赖项和插件:
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>something</artifactId>
<version>${project.version}</version>
<classifier>uber</classifier>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
请注意以下有关包括依赖项的信息:
在该模块上的maven部署阶段结束时,已着色的jar将上传到存储库中,您可以将其作为依赖项添加到外部项目中,如下所示:>
<dependency>
<groupId>com.sample</groupId>
<artifactId>something-uber</artifactId>
<version>0.1.0</version>
</dependency>
从解决方案“ A”开始,如果要避免在存储库中提供 thin jar ,则应避免在第1点上在maven-shade-plugin上指定 finalName 配置,因此也请避免使用 build-helper-maven-plugin 插件,因为没有要附加的新工件。 这样做,在模块上部署目标/上只有uber jar作为默认模块(不带分类器):
7M something-0.1.0.jar
您还应该跳过上传操作,否则在这里还将上传两个胖子( something-0.1.0.jar 和 something-uber-0.1.0.jar )。 为此,在同一模块上添加以下插件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
在第2点的结尾,只需避免在添加依赖项时指定分类器,如下所示:
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>something</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
在寻找解决方案一段时间后,我决定从GitHub派发 maven-deploy-plugin 插件并尝试一项新功能,以跳过添加第一个模块时创建的有阴影的jar插件配置如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-SNAPSHOT</version>
<configuration>
<skipAttachedArtifacts>
<artifact>
<groupId>com.sample</groupId>
<artifactId>something</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<classifier>uber</classifier>
</artifact>
</skipAttachedArtifacts>
</configuration>
</plugin>
当前使用 maven-deploy-plugin 插件将所有工件从部署中排除,而此处的目标是仅排除特定工件。在我的叉子上,我引入了“ skipAttachedArtifacts”配置参数,以便指定从部署中排除的附加工件。
这是我在GitHub上的分支项目上的链接: https://github.com/gregorycallea/maven-deploy-plugin
这里是我在apache插件项目上提交的拉取请求的链接: https://github.com/apache/maven-deploy-plugin/pull/3
答案 1 :(得分:1)
经典场景是:
dependency
文件中的pom.xml
元素),然后将它们打包在一个超级jar中作为Maven工件dependency
元素)时,Maven会检查它的<artifact>-<version>.pom
文件(与最终工件一起发布到Maven存储库中),这是基本上是其原始pom.xml
文件的重命名副本,其中声明了依赖项(dependency
元素)(确切地说是打包到uber-jar中的依赖项)。由于您已将它们打包,因此您可以忽略.pom
文件(及其dependencies
元素),因为您需要添加exclusions
如下:
<dependency>
<groupId>com.sample</groupId>
<artifactId>something-uber</artifactId>
<version>some-version</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
注意:上述功能仅在Maven 3.2.1
之后可用。
因此,您向Maven表明,您不希望任何传递依赖,Maven dependency mediation则不会触发它们。
作为旁注:将uber-jar作为项目的依赖项并不是一个好习惯:它只会使维护变得更难,因为您无法通过dependencyManagement
或{来控制传递依赖项{1}}依赖项目的顺序。因此,每当依赖(其中一个传递依赖)需要维护(更改版本等)时,您将始终需要重新打包超级jar,并且对依赖项目的控制更少(再次,更难维护)。 / p>