用 Maven 做一个大罐子

我有一个代码库,我想分发为 jar。它还依赖于外部 jar,我想把它打包到最后一个 jar 中。

我听说这可以用 maven-assembly-plug-in来完成,但是我不知道怎么做。谁能给我举几个例子。

现在,我正在使用 fat jar 来捆绑最后一个 jar。

152018 次浏览

你可以使用 文明-阴影-插件

在构建中配置阴影插件之后,命令 mvn package将创建一个具有所有依赖项的 jar。

注意: 如果您是一个弹簧启动应用程序,请阅读答案的末尾

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

...
<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-endencies”的胖 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 application 使用下面的插件(选择合适的版本)

<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>

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

<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: 在项目 主页中可以使用配置选项。

注意2: 由于这样或那样的原因,onejar-Maven-plugin 项目没有在 MavenCentral 发布。但是,Jolira.com跟踪原始项目并使用 groupId com.jolira将其发布到。

您可能需要 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>

参考文献:

实际上,加上

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

对 maven-jar-plugin 的声明不会为我将主类条目添加到清单文件中。 我不得不将它添加到 maven-Assembly-plugin 中,以便将其输入到清单中

另一种方法是使用专用的 阴影插件来构建 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>