0

我发布这个问题是因为我目前正在使用 Maven 来构建胖罐子。我们所有的项目都是插件,所以我们的目标是从 MANIFEST.MF 文件中获取所有依赖项,以便构建胖 jar。
第一个问题是我们的一些依赖项在系统范围内(例如 com.google.guava),当我们构建中间 jars 时,进一步的项目需要它们,它们在提供的范围内。所以我决定避免使用 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”加载(如果你有任何解决方案,我也很感兴趣)。
我遇到的问题是,对于一个特定的项目,我们需要在我们的一个 MANIFEST.MF 文件中使用 bundle org.apache.commons.lang;bundle-version="2.6.0" ,它会以某种方式导致异常:

执行目标 org.apache.maven.plugins:maven-assembly-plugin:3.3.0:single 的组装失败:org/apache/commons/lang/math/JVMRandom.class 的 SHA1 签名文件摘要无效

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

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

对于每个标签,但我仍然遇到相同的错误。
最后,我有点不知道我应该做什么。忽略依赖(在运行最终的 jar 时会导致错误)?找到忽略此类错误的方法?
感谢您的阅读。

4

1 回答 1

0

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

1. Maven 组装

该插件似乎适用于 tycho,因为它可以配置为捕获您需要的所有依赖项(如问题中所述)。
但它不提供 JAR 支持中的任何 JAR,因此您可以解压缩所有依赖项但可能存在一些依赖项冲突,或者您可以将所有依赖项打包但您需要在 JAR ClassLoader 中编写自己的 JAR(如 Capsule 或 One Jar,除非它们不再更新)。

2. Maven 阴影

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

3. Maven-胶囊

这个插件可以工作,但在某些情况下,我需要在一些pom.xml文件中有多余的依赖项,而 capsule 已经五年没有更新了,所以依赖它似乎是个坏主意。

4. Maven 包

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

5.spring-boot-maven

它是唯一使它几乎可以立即工作的插件。它重新打包捆绑包及其所有依赖项并提供自定义 ClassLoader 以使其可执行。您可以在插件的选项中包含系统范围,它经常更新,并且有自己的精确文档。
唯一奇怪的是,在重新打包时,它会获取 classpath/MANIFEST.MF 文件中的所有依赖项并以 .jar 为后缀,如果 jar 文件直接包含在 classpath 中,则可能会导致.jar.jar文件,以及package-lib/ 文件夹。

希望这将有助于进一步的maven用户!

于 2021-11-29T13:31:20.553 回答