【问题标题】:Maven "shaded" JAR is prefixed with "original" in the file nameMaven “shaded” JAR 在文件名中以“original”为前缀
【发布时间】:2011-05-04 13:46:23
【问题描述】:

我正在使用“shade”Maven2 插件构建一个整体 JAR,其中所有 Java 依赖项捆绑在一起。 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>
                <finalName>${project.artifactId}-${project.version}-SHADED</finalName>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>com.mypackage.MyClass</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

但是,构建结果很奇怪。看来这个 Maven 插件实际上创建了两个文件:

myartifact-1.0.0-SHADED.jar  (zero bytes)
original-myartifact-1.0.0-SHADED.jar  (10 MB)

前缀为“original”的 JAR 文件已正确构建,并且功能正常。我想我可以重命名它以去掉那个前缀,然后继续我的快乐之路。

但是,我很好奇“shade”插件在这里会发生什么。看起来“原始”文件是临时工作空间类型的东西,打算在进程结束时重命名,而最终重命名根本没有完成。但是,没有明显的解释(即文件系统权限等)。有没有人见过这个?

【问题讨论】:

  • 您可以考虑将复选标记切换为 Stewart 的答案。
  • 解决方法是设置&lt;outputDirectory&gt;/tmp&lt;/outputDirectory&gt;original-*.jar 文件仍在编写中,但至少不在开发路径中。

标签: java maven-2


【解决方案1】:

在@Stewart 之后提供了一个更好的答案(没有冒犯任何一个:D):

你得到原来的-*混乱的原因可能是双重的:

  1. 指定 &lt;finalName&gt; 意味着您想要一个不同于 Maven 默认为您提供的名称(即:与工件名称相同:artifactId-version.jar 或 artifactId-version-shaded.jar)。如果您指定与两者之一相同的最终名称,它将尝试将旧名称备份为 original-*.jar,然后用新的阴影覆盖它。在您的情况下,您告诉它制作最终的 JAR *-shaded.jar,当它来自 Maven 时已经是这种情况(在默认情况下将其放入 artifactId-version.jar 之前),所以它首先支持将旧的*-shaded.jar 升级为original-*-shaded.jar,然后在将字节写入新的*-shaded.jar 时出错,因为旧的消失了(他们似乎重命名了它)。

  2. (这是我的情况)使用&lt;shadedClassifierName&gt;,它只更改Maven 用于生成*-shaded.jar 的后缀,结合&lt;finalName&gt; 也可以产生相同的结果。如果您愿意,您可以只使用&lt;shadedClassifierName&gt; 并指定一个不同的后缀并完成它,而不必在整个过程中指定&lt;finalName&gt;。在我的情况下,我都设置了将输出命名为相同的东西:即:artifactId-version-all.jar,但使用 'all' 作为分类器让我回到了 #1 中描述的场景。

【讨论】:

  • 您可能还想使用 但这只是意味着您希望在将阴影工件与原始工件一起安装/部署之后在 Maven 存储库中使用阴影工件。在命名方面并没有真正改变任何东西。
【解决方案2】:

我知道这个问题很老,但认为值得添加以下信息。

我认为史蒂夫最初想要的输出是maven-shade-plugin documentation的此页面上给出的输出。

<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>

【讨论】:

  • Maven 是关于合理的默认值;但是这里的 Shale 默认值几乎是不合理的:它更改了 jar 的内容,该 jar 具有在没有 Shale 的情况下构建的原始默认名称。正因为如此,一些依赖于默认命名的 jar 以仅具有原始默认内容的 IDE 现在会因为在该 jar 中看到额外/Shaled 内容而吓坏了。从这个意义上说,程序集插件具有更合理的默认值 - 保持默认 jar 的原始名称和内容不变,并为胖 jar 提供不同的名称。
【解决方案3】:

Maven 的构建步骤将创建 jar target/artifact-version.jar

然后阴影插件运行。它通常将该 jar 重命名为 target/original-artifact-version.jar,并将阴影 JAR 命名为 target/artifact-version.jar

但是,您将 Shade 插件配置为使用不同的名称。除非有充分的理由,否则我会从您的配置中删除 &lt;finalName&gt;,并接受 Shade 插件想要为您提供的功能。

【讨论】:

  • 就是这样。叹息......我很享受我对 Maven 的实验,我喜欢它给我的力量。但是,我可以在该社区中没有太多“不要与 Maven 对抗”和“做 Maven 想要的”文化。如果您要求 Maven 执行错误的做法,我可以理解抛出错误或警告消息......但是当 Maven 只是以错误的方式失败时,这些短语听起来像是空洞的借口。如果插件“不希望”我在 &lt;finalName&gt; 元素中声明自定义最终名称......那么为什么要提供 &lt;finalName&gt; 元素作为架构的一部分呢?这只是一个错误。
  • 哦,我不是想抱怨你,Anon……只是抱怨 Maven 和它的普通社区! :) 感谢您的帮助。
  • @Steve - 没有冒犯。相信我,我一直在抱怨 Maven。现在我在抱怨,因为我无法轻易覆盖我的 settings.xml 中的部署 URL :-) 有时我不得不查看源代码以找出问题所在。
  • @swordfish 阴影 jar(除非另有配置)仅包含您项目的所有依赖项 - 因此,如果您的项目包含“main”,则无需指定长类路径。使用 shade 插件,你还可以指定一个 mainClass,这样你就可以制作一个可执行的 jar:java -jar myproj-1.0.jar
  • 嗨。你说首先Maven构建没有依赖关系的原始jar,然后使用前缀“original-”重命名它,然后使用shade插件构建具有所有依赖关系的最终jar。为什么要构建没有依赖关系的原始jar,然后重命名它?是否可以设置为忽略没有依赖项的原始 jar 的构建,而只构建一个具有所有依赖项的 jar?没有所有这些与构建无用的罐子然后重命名它们的舞蹈?
猜你喜欢
  • 2015-10-07
  • 2016-06-04
  • 2016-05-22
  • 2020-07-06
  • 2019-12-23
  • 2012-12-04
  • 2016-11-27
  • 2014-12-09
  • 1970-01-01
相关资源
最近更新 更多