如何使用Maven创建一个JarJar'd工件,其中工件的使用不会提取传递依赖?

时间:2011-04-19 19:34:11

标签: maven classpath software-distribution artifact jarjar

我目前有一个用Maven构建的Java测试库,并以jar形式发布。我的项目依赖于一个非常常见的库(Objectweb ASM),并且我遇到过类似路径中已经存在早期且不兼容的ASM版本的问题。因此,我开始使用jarjar-maven-plugin来创建jar,在内部重新打包ASM,它不会与另一个版本的ASM冲突。

执行得很好,我的库可以作为依赖项拉入,没有问题。

但是,因为我的项目在ASM上具有编译范围依赖关系,所以每当客户端项目添加我的库时,传递依赖关系都会被拉入。因此,假设,如果他们使用特定版本的ASM,并且他们还将我依赖的版本添加到类路径中,则它们具有未定义的行为。我想避免这种情况,并允许客户端依赖JarJar'd工件,而不会让Maven不必要地和可能危险地降低传递依赖性。

如何创建一个JarJar'd工件,用户可以依赖它而不会产生传递依赖?

3 个答案:

答案 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>