我目前有一个用Maven构建的Java测试库,并以jar形式发布。我的项目依赖于一个非常常见的库(Objectweb ASM),并且我遇到过类似路径中已经存在早期且不兼容的ASM版本的问题。因此,我开始使用jarjar-maven-plugin来创建jar,在内部重新打包ASM,它不会与另一个版本的ASM冲突。
执行得很好,我的库可以作为依赖项拉入,没有问题。
但是,因为我的项目在ASM上具有编译范围依赖关系,所以每当客户端项目添加我的库时,传递依赖关系都会被拉入。因此,假设,如果他们使用特定版本的ASM,并且他们还将我依赖的版本添加到类路径中,则它们具有未定义的行为。我想避免这种情况,并允许客户端依赖JarJar'd工件,而不会让Maven不必要地和可能危险地降低传递依赖性。
如何创建一个JarJar'd工件,用户可以依赖它而不会产生传递依赖?
答案 0 :(得分:17)
我通过放弃jarjar-maven-plugin并恢复到maven-shade-plugin找到了解决这个问题的方法。这允许在您自己的命名空间内重新打包类,设置jar的主类,最重要的是,将生成的pom重写为 not 包括现在捆绑的编译时依赖项。
我的pom.xml中实现此目的的部分是:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>true</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>org.objectweb.asm</pattern>
<shadedPattern>${repackage.base}.org.objectweb.asm</shadedPattern>
</relocation>
</relocations>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${package.base}.my.MainClass</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
此配置的重要部分是:
shadedArtifactAttached
当设置为false时,表示阴影jar将替换通常会生成的主要工件。这默认为false,但值得指出。createDependencyReducedPom
当设置为true时表示当部署或安装着色jar时,部署的pom.xml将不包含已重新打包到jar中的编译范围依赖项。relocation
这些元素配置依赖关系中的文件如何重新打包到着色jar中。在上面的示例中,规范名称以org.objectweb.asm
开头的任何类都将移动到${package.base}.org.objectweb.asm
,因此当打包在jar中时,jar中将具有等效的文件路径。使用此配置,当我的项目部署时,当客户端声明我的项目的编译范围依赖项时,它只会拉入阴影jar,并且没有传递依赖项。
答案 1 :(得分:1)
考虑尝试使用maven-shade-plugin,它允许各种精细控制。
答案 2 :(得分:0)
也许设置<optional>
属性可以适用于您的情况。在java测试库pom中指定类似以下的内容。
<dependencies>
<dependency>
<groupId>asm.group</groupId>
<artifactId>asm</artifactId>
<version>x.y</version>
<optional>true</optional>
</dependency>
...
</dependencies>