ChatGPT解决这个技术问题 Extra ChatGPT

使用 maven 构建一个胖罐子

我有一个代码库,我想将它作为 jar 分发。它还依赖于外部 jar,我想将其捆绑在最终的 jar 中。

我听说这可以使用 maven-assembly-plug-in 完成,但我不明白如何。有人可以指点我一些例子。

现在,我正在使用 fat jar 来捆绑最终的 jar。我想使用 maven 实现同样的目标。


f
forkdbloke

注意:如果您是spring-boot应用程序,请阅读答案末尾

将以下插件添加到您的 pom.xml 最新版本可以是 found at

...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>CHOOSE LATEST VERSION HERE</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>assemble-all</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
...

配置此插件后,运行 mvn package 将生成两个 jar:一个仅包含项目类,另一个包含所有依赖项且后缀为“-jar-with-dependencies”的 fat jar。

如果您想在运行时进行正确的 classpath 设置,那么还要添加以下插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>fully.qualified.MainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

对于 Spring Boot 应用程序,只需使用以下插件(选择适当的版本)

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <fork>true</fork>
        <mainClass>${start-class}</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

这个插件的当前版本现在是 2.4
现在已弃用,应使用 maven-shade-plugin 代替。请参阅@phlogratos 答案:stackoverflow.com/a/16222965/274350
maven-assembly-plugin 可以最小化 fat jar 的大小吗?
@Richard 你在哪里看到它被弃用了?我在这里找不到任何东西maven.apache.org/plugins/maven-assembly-plugin
@user3833308 “已弃用”可能是错误的词,但 maven.apache.org/plugins/maven-assembly-plugin 中的文档说“如果您的项目想要将您的工件打包在 uber-jar 中,则程序集插件仅提供基本支持。要获得更多控制,请使用 Maven Shade插入。”
C
Community

您可以使用 maven-shade-plugin

在您的构建中配置遮光插件后,命令 mvn package 将创建一个包含所有依赖项合并到其中的单个 jar。


现在这是正确的方法。 maven-assembly-plugin 文档指出:“如果您的项目想要将您的工件打包到 uber-jar 中,则程序集插件仅提供基本支持。要获得更多控制,请使用 Maven Shade 插件。”
但是我如何获取单个 .jar 并将其用于发布?
我不同意这是现在的“正确”方式。如果您只想要基本行为,那么您绝对可以继续使用程序集插件。 shade插件做了一些高级的事情,比如重写字节码来修改依赖包的名称,一旦你开始使用生产代码,你就会引入额外的风险,如果你没有充分的理由,这是不值得的。
P
Patrick Favre

也许您想要 maven-shade-plugin、捆绑依赖项、最小化未使用的代码并隐藏外部依赖项以避免冲突。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <minimizeJar>true</minimizeJar>
                        <createDependencyReducedPom>true</createDependencyReducedPom>
                        <dependencyReducedPomLocation>
                            ${java.io.tmpdir}/dependency-reduced-pom.xml
                        </dependencyReducedPomLocation>
                        <relocations>
                            <relocation>
                                <pattern>com.acme.coyote</pattern>
                                <shadedPattern>hidden.coyote</shadedPattern>
                            </relocation>
                        </relocations>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

参考:

http://maven.apache.org/plugins/maven-shade-plugin/plugin-info.html

http://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html


如果遇到 Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found,只需删除 <minimizeJar>true</minimizeJar>
如果您收到“java.lang.SecurityException: Invalid signature file digest for Manifest main attributes”异常,那么对上述配置部分的补充有助于:stackoverflow.com/a/6743609/38368
F
Faisal Feroz

实际上,添加

<archive>
   <manifest>
    <addClasspath>true</addClasspath>
    <packageName>com.some.pkg</packageName>                     
    <mainClass>com.MainClass</mainClass>
  </manifest>
</archive>

对 maven-jar-plugin 的声明不会为我将主类条目添加到清单文件中。我必须将它添加到 maven-assembly-plugin 才能在清单中得到它


m
matsev

您可以使用 onejar-maven-plugin 进行打包。基本上,它将您的项目及其依赖项组装为一个 jar,不仅包括您的项目 jar 文件,还包括所有外部依赖项作为“jar of jars”,例如

<build>
    <plugins>
        <plugin>
            <groupId>com.jolira</groupId>
            <artifactId>onejar-maven-plugin</artifactId>
                <version>1.4.4</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>one-jar</goal>
                        </goals>
                    </execution>
                </executions>
        </plugin>
    </plugins>
</build>

注 1:项目 home page 中提供了配置选项。

注意 2:出于某种原因,onejar-maven-plugin 项目未在 Maven 中心发布。但是,jolira.com 会跟踪原始项目并将其发布到 groupId com.jolira


是否可以选择要打包的依赖项?例如,如果 a.jar 和 b.jar 是外部 jar,我只想将 a.jar 打包到最终的 jar 中,这是否可能/可配置?
我还看到一个罐子的东西也被捆绑在最后的罐子里。这大大增加了最终罐子的大小。是否可以选择您打算包含在最终 jar 中的外部 jar?这是单罐日志:pastebin.com/UwniQJ2X
我不知道您是否可以配置包含的内容。基本上,one-jar 包含项目指定的所有依赖项,包括传递依赖项,所以是的,如果您有很多依赖项,最终的 jar 可能会变得很大。 one-jar 会增加一些开销,以使 Java 使用“jar of jars”结构。
S
Stanislav

另一种方法是使用 maven shade 插件来构建 uber-jar

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version> Your Version Here </version>
    <configuration>
            <!-- put your configurations here -->
    </configuration>
    <executions>
            <execution>
                    <phase>package</phase>
                    <goals>
                            <goal>shade</goal>
                    </goals>
            </execution>
    </executions>
</plugin>