Maven 程序集:忽略已签名的依赖项

Maven assembly : ignore signed dependencies

我发布这个问题是因为我目前正在使用 Maven 来构建 fat jar。我们所有的项目都是插件,所以我们的目标是从 MANIFEST.MF 文件中获取所有依赖项以构建 fat jars。
第一个问题是我们的一些依赖项在系统范围内(例如 com.google.guava),并且当我们构建后续项目需要的中间 jar 时,它们在提供的范围内。所以我决定避免使用 shade-plugin,因为它似乎无法配置范围。
我选择使用 maven-assembly,因为它似乎是处理我们构建的最具表现力的方式,使用以下自定义程序集文件从所有范围收集依赖项:

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
    <id>jar-with-dependencies</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>provided</scope>
        </dependencySet>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>system</scope>
        </dependencySet>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>runtime</scope>
        </dependencySet>
    </dependencySets>
</assembly>

我必须将 unpack 设置为 true,因为我们需要可执行 jar,而且在使用 maven-assembly 时似乎也无法轻松处理“jar-in-jar”加载(如果您对此有任何解决方案,我也有兴趣)。
我遇到的问题是,对于一个特定的项目,我们需要 bundle org.apache.commons.lang;bundle-version="2.6.0" 在我们的 MANIFEST.MF 文件之一中,它会以某种方式导致异常:

Execution make-assembly of goal org.apache.maven.plugins:maven-assembly-plugin:3.3.0:single failed: invalid SHA1 signature file digest for org/apache/commons/lang/math/JVMRandom.class

当我调查时,我在依赖项中发现了一个签名的清单文件 + ECLIPSE_.RSA & ECLIPSE_.SF,所以我试图在解包时至少排除那些文件:

...
            <unpackOptions>
                <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                </excludes>
            </unpackOptions>
...

对于每个标签,但我仍然遇到相同的错误。
最后,我对我应该做什么感到困惑。忽略依赖关系(当 运行 最终 jar 时会导致错误)?想办法忽略此类错误?
顺便感谢阅读。

经过进一步调查,这里有一个简短的总结。
Tycho 将 外部依赖项 存储在 系统范围 中,将 模块依赖项 存储在 提供范围,所以如果你想要可执行的jar,你需要找到一个插件来捕获这些。
这是我测试过的插件:

1. Maven 程序集

这个插件似乎适合 tycho,因为它可以配置为捕获您需要的所有依赖项(如问题中所述)。
但是它不提供任何 JAR in JAR 支持,所以要么你可以解压所有的依赖,但你可能会有一些依赖冲突,或者你可以保留所有的依赖打包,但你需要在 JAR ClassLoader 中编写你自己的 JAR(作为 Capsule 或 One Jar,除了它们不再更新)。

2。 Maven 阴影

这个插件显然在 JAR 支持中提供了这样的 JAR,但它只能在运行时范围内工作,我找不到改变这个默认范围的方法,所以我也不得不继续前进。

3。 Maven 胶囊

这个插件可以,但在某些情况下,我需要在一些pom.xml文件中有冗余依赖,并且胶囊已经五年没有更新所以它依赖它似乎是个坏主意。

4。 Maven 包

这个插件需要添加 .bnd 文件,所以它不能满足我对 MANIFEST-first 插件的需求。

5. Spring-boot-maven

它是唯一一个几乎可以瞬间运行的插件。它重新打包一个包及其所有依赖项,并提供一个自定义类加载器以使其可执行。您可以在插件的选项中包含系统范围,它经常更新,并且有自己的精确文档。
唯一奇怪的是,重新打包时,它会将classpath/MANIFEST.MF文件中的所有依赖项都带上.jar作为后缀,这会导致.jar.jar文件,如果 jar 文件直接包含在类路径中,以及 package-lib/ 文件夹。

希望这对更多的 maven 用户有帮助!