【问题标题】:Maven - Is there a way to easily create an 'uber' jar with all the dependencies relocated?Maven - 有没有办法轻松创建一个所有依赖项重新定位的“超级”jar?
【发布时间】:2015-03-30 06:36:44
【问题描述】:

我们需要使用 Maven 构建一个 jar,以包含其所有依赖项的方式,而且所有这些依赖项都被重命名(重新定位)。

假设我们自己的包都以com.mycompagny.projectx.*"开头。我们希望项目依赖项的包重命名为以"embedded"开头,但不是我们自己的类。

maven-shade-plugin 为例,我无法做到这一点:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</version>
    <configuration>
        <shadedArtifactAttached>true</shadedArtifactAttached>
        <createDependencyReducedPom>true</createDependencyReducedPom>
        <artifactSet>
            <includes>
                 <include>*.*</include>
            </includes>
        </artifactSet>
        <relocations>
            <relocation>
                <pattern>*</pattern>
                <shadedPattern>embedded.</shadedPattern>
                <excludes>
                    <exclude>com.mycompagny.projectx.*</exclude>
                </excludes>
            </relocation>
        </relocations>
    </configuration> 
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
</plugin>

这里&lt;pattern&gt;*&lt;/pattern&gt; 无效。另外,如果我使用&lt;pattern&gt;&lt;/pattern&gt;(空字符串),那么所有内容都会重新定位到“嵌入式”包,甚至是资源(也是“META-INF”目录)!当然,我们希望资源保留在 jar 的根目录中。

我想我们可以创建多个 &lt;relocation&gt; 元素,每个依赖包一个,但这将是很多工作:&lt;relocation&gt;com&lt;/relocation&gt;&lt;relocation&gt;net&lt;/relocation&gt;&lt;relocation&gt;javax&lt;/relocation&gt; 等。

知道如何在不触及我们自己的类、资源和“META-INF”目录的情况下轻松地重新定位 uber jar 中的所有依赖项吗?

【问题讨论】:

    标签: java maven jar maven-shade-plugin


    【解决方案1】:

    更新:此解决方案实际上不起作用,请阅读到最后。

    我通过查看maven-shade-plugin的源代码找到了解决方案!它似乎没有在任何地方记录,但是有一个 &lt;rawString&gt; 参数可以添加到 &lt;relocation&gt; 元素中,因此它将 &lt;pattern&gt;&lt;shadedPattern&gt; 视为 正则表达式模式 而不是包/文件名。

    maven-shade-plugin 代码然后使用类似:

    path.replaceAll(pattern, shadedPattern)
    

    处理这些模式。

    例子:

    <relocation>
        <pattern>^([^/]*\.properties)$</pattern>
        <shadedPattern>embedded/$1</shadedPattern>
        <rawString>true</rawString>
    </relocation>
    

    这是一个虚拟示例,它重新定位根目录中的所有 .properties 文件。使用这种技术,可以准确控制重定位的内容和方式,我很确定。

    这是一个更好的例子,它可以满足我的需要(尽管还有一些测试要做):

    <relocation>
        <pattern>^(?!(com/mycompagny/|META-INF))(.*/.*)$</pattern>
        <shadedPattern>embedded/$2</shadedPattern>
        <rawString>true</rawString>
    </relocation>
    

    更新:遗憾的是,最后一种模式意味着所有使用的东西都将被重命名,除了“com.mycompagny”和 META-INF 文件夹。问题是,java.lang.Object 之类的东西将被重命名!当代码运行时,会抛出类似的异常:

    java.lang.ClassNotFoundException: embedded.java.lang.Object
    

    【讨论】:

    • 虽然这并没有解决您的问题...这IS 是一个非常有用的未记录功能。我有需要移动到不同文件夹的资源(不是源代码,也不是包结构)。感谢您的来信。
    猜你喜欢
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    • 2015-07-12
    • 2014-01-08
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多