如何使用Maven创建具有依赖关系的可执行/可运行JAR?

我想将我的项目打包在一个可执行的JAR中进行分发。

如何使Maven项目将所有依赖项JAR打包到我的输出JAR中?

1762584 次浏览
<build><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><archive><manifest><mainClass>fully.qualified.MainClass</mainClass></manifest></archive><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration></plugin></plugins></build>

然后你用

mvn clean compile assembly:single

编译目标应在汇编之前添加:不包括您自己项目上的代码。

在评论中查看更多详细信息。


通常,此目标与自动执行的构建阶段相关联。这确保在执行mvn install或执行部署/发布时构建JAR。

<build><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><archive><manifest><mainClass>fully.qualified.MainClass</mainClass></manifest></archive><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration><executions><execution><id>make-assembly</id> <!-- this is used for inheritance merges --><phase>package</phase> <!-- bind to the packaging phase --><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build>

IAdapter的回答并重新格式化它,我们有:

<build><plugins><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><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration></plugin></plugins></build>

接下来,我建议将其作为构建的自然部分,而不是显式调用的东西。要使其成为构建的一个组成部分,请将此插件添加到您的pom.xml并将其绑定到package生命周期事件。然而,一个问题是,如果将其放入您的pom.xml中,您需要调用assembly:single目标,而如果从命令行手动执行它,您将调用“汇编:汇编”。

<project>[...]<build><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><archive><manifest><addClasspath>true</addClasspath><mainClass>fully.qualified.MainClass</mainClass></manifest></archive><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration><executions><execution><id>make-my-jar-with-dependencies</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin>[...]</plugins>[...]</build></project>

如果您真的想在单个结果JAR中重新打包其他JAR内容,另一种选择是Maven组装插件。它解包,然后通过<unpack>true</unpack>将所有内容重新打包到目录中。然后您将有第二次将其构建到一个大型JAR中。

另一种选择是OneJar插件。这一步完成上述重新打包操作。

Ken Liu在我看来是对的。Maven依赖插件允许您扩展所有依赖项,然后您可以将其视为资源。这允许您将它们包含在主要工件中。组装插件的使用创建了一个难以修改的辅助工件-在我的情况下,我想添加自定义清单条目。我的POM文件最终为:

<project>...<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>unpack-dependencies</id><phase>package</phase><goals><goal>unpack-dependencies</goal></goals></execution></executions></plugin></plugins>...<resources><resource><directory>${basedir}/target/dependency</directory><targetPath>/</targetPath></resource></resources></build>...</project>

您可以使用maven-依赖插件,但问题是如何创建可执行的JAR文件。要做到这一点,需要对Matthew Franglen的回应进行以下更改(顺便说一句,从干净的目标开始使用依赖插件需要更长的时间来构建):

<build><plugins><plugin><artifactId>maven-jar-plugin</artifactId><configuration><archive><manifest><mainClass>fully.qualified.MainClass</mainClass></manifest></archive></configuration></plugin><plugin><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>unpack-dependencies</id><phase>package</phase><goals><goal>unpack-dependencies</goal></goals></execution></executions></plugin></plugins><resources><resource><directory>${basedir}/target/dependency</directory></resource></resources></build>

将所有依赖项嵌入项目的JAR文件本身可能不是一个好主意。

我明白了这一点(易于部署/使用),但这取决于您的项目的用例(可能有替代方案(见下文))。

如果你完全独立使用它,为什么不呢?

但是,如果您在其他上下文中使用您的项目(例如在Web应用程序中,或者放置在其他JAR所在的文件夹中),您的类路径中可能会有JAR重复项(文件夹中的重复项,JAR文件中的重复项)。

一个不错的选择:

  • 将应用程序部署为ZIP或战争文件:存档包含项目的JAR文件和所有依赖的JAR文件;
  • 使用动态类加载器机制(请参阅Spring框架,或者您可以轻松地自己执行此操作)来拥有项目的单个切入点(要启动的单个类-请参阅另一个答案中的Manifest机制),这将(动态地)向当前类路径添加所有其他需要的JAR文件。

像这样,最后只有一个清单和一个“特殊的动态类加载器main”,您可以使用以下命令开始您的项目:

java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass

它将像这样工作:

<plugin><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>unpack-dependencies</id><phase>generate-resources</phase><goals><goal>unpack-dependencies</goal></goals></execution></executions></plugin>

解包必须处于生成资源阶段,否则它将不会被包含为资源。

要从命令行本身创建可执行JAR,只需从项目路径运行以下命令:

mvn assembly:assembly

使用maven-shad-plugin相关链接将所有依赖项打包到一个über-JAR文件中。它也可以用于通过指定主类来构建可执行的JAR文件。在尝试使用maven-Assembly和maven-jar后,我发现这个插件最适合我的需求。

我发现这个插件特别有用,因为它合并了特定文件的内容而不是覆盖它们。当JAR文件中有同名的资源文件并且插件尝试打包所有资源文件时,这是必要的。

请看下面的例子:

<plugins><!-- This plugin provides the capability to packagethe artifact in an über-JAR file, includingits dependencies and to shade - i.e. rename -the packages of some of the dependencies. --><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><artifactSet><!-- Signed JAR files--><excludes><exclude>bouncycastle:bcprov-jdk15</exclude></excludes></artifactSet>
<transformers><transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><!-- Main class --><mainClass>com.main.MyMainClass</mainClass></transformer>
<!-- Use resource transformers to prevent file overwrites --><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>properties.properties</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer"><resource>applicationContext.xml</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/cxf/cxf.extension</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer"><resource>META-INF/cxf/bus-extensions.xml</resource></transformer></transformers></configuration></execution></executions></plugin></plugins>

您可以使用依赖插件在包阶段之前在单独的目录中生成所有依赖项,然后将其包含在清单的类路径中:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy-dependencies</id><phase>prepare-package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/lib</outputDirectory><overWriteReleases>false</overWriteReleases><overWriteSnapshots>false</overWriteSnapshots><overWriteIfNewer>true</overWriteIfNewer></configuration></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><mainClass>theMainClass</mainClass></manifest></archive></configuration></plugin>

或者,使用${project.build.directory}/classes/lib作为OutputDirectory将所有JAR文件集成到主JAR文件中,但随后您需要添加自定义类加载代码来加载JAR文件。

使用maven-plugin-2.2.1定位共享程序集文件有什么问题?

尝试使用描述符/描述符配置参数而不是描述符/描述符或描述符/描述符参数。

它们都没有做你需要的:在类路径上查找文件。当然,您需要添加共享程序集驻留在maven-plugin-plugin的类路径上的包(见下文)。如果您使用的是Maven 2. x(不是Maven 3. x),您可能需要在pluginManagement部分的最顶层父级pom.xml中添加此依赖项。

查看这个了解更多详情。

类:org.apache.maven.plugin.assembly.io.DefaultAssemblyReader

示例:

<!-- Use the assembly plugin to create a zip file of all our dependencies. --><plugin><artifactId>maven-assembly-plugin</artifactId><version>2.2.1</version><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals><configuration><descriptorId>assembly-zip-for-wid</descriptorId></configuration></execution></executions><dependencies><dependency><groupId>cz.ness.ct.ip.assemblies</groupId><artifactId>TEST_SharedAssemblyDescriptor</artifactId><version>1.0.0-SNAPSHOT</version></dependency></dependencies></plugin>

您可以将以下内容添加到pom.xml文件中:

<build><defaultGoal>install</defaultGoal><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.6</source><target>1.6</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.3.1</version><configuration><archive><manifest><addClasspath>true</addClasspath><mainClass>com.mycompany.package.MainClass</mainClass></manifest></archive></configuration></plugin><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifest><mainClass>com.mycompany.package.MainClass</mainClass></manifest></archive></configuration><executions><execution><id>make-my-jar-with-dependencies</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build>

之后,您必须通过控制台切换到pom.xml文件所在的目录。然后您必须执行mvn组装:单个,然后希望构建具有依赖项的可执行JAR文件。您可以在切换到cd。/目标的输出(目标)目录并使用类似于java-jarmavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar的命令启动JAR时检查它。

我用Apache Maven 3.0.3测试了这个。

您可以将maven-shade-pluginmaven-jar-plugin组合在一起。

  • maven-shade-plugin将类和所有依赖项打包在一个JAR文件中。
  • 配置maven-jar-plugin以指定可执行JAR文件的主类(请参阅设置类路径,“使Jar可执行”一章)。

maven-jar-plugin的示例POM配置:

        <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.3.2</version><configuration><archive><manifest><addClasspath>true</addClasspath><mainClass>com.example.MyMainClass</mainClass></manifest></archive></configuration></plugin>

最后通过调用以下命令创建可执行JAR文件:

mvn clean package shade:shade

我长期以来一直使用Maven组装插件,但我找不到#0问题的解决方案。现在,我正在使用另一个插件-一个jar-maven-plugin。下面是一个示例(mvn package构建JAR文件):

<plugin><groupId>org.dstovall</groupId><artifactId>onejar-maven-plugin</artifactId><version>1.3.0</version><executions><execution><configuration><mainClass>com.company.MainClass</mainClass></configuration><goals><goal>one-jar</goal></goals></execution></executions></plugin>

您需要为该插件添加一个存储库:

<pluginRepositories><pluginRepository><id>onejar-maven-plugin.googlecode.com</id><url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url></pluginRepository></pluginRepositories>

maven汇编插件为我工作得很好。

我花了好几个小时使用maven-依赖-插件,但无法使其正常工作。主要原因是我必须在配置部分明确定义工件项,这些项目应该包含在留档中描述的内容中。

有一个例子,当你想要使用它时,比如:mvn dependency:copy,其中没有包含任何artifactItems,但它不起作用。

对我有用的东西是:

  <plugin><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>unpack-dependencies</id><phase>prepare-package</phase><goals><goal>unpack-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/classes</outputDirectory></configuration></execution>
</executions></plugin>
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><executions><execution><id>unpack-dependencies</id><phase>package</phase></execution></executions><configuration><archive><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><mainClass>SimpleKeyLogger</mainClass></manifest></archive></configuration></plugin>

我有一个非同寻常的案例,因为我的依赖是系统一:

<dependency>..<scope>system</scope><systemPath>${project.basedir}/lib/myjar.jar</systemPath></dependency>

我已经更改了代码由user189057提供的更改:

  1. maven依赖插件在“准备包”阶段执行
  2. 我将解压类直接提取到“目标/类”

可执行文件-jar-with-maven-例子(GitHub)

备注

这些优点和缺点由Stephan提供。


用于手动部署

  • 优点
  • 缺点
    • 依赖项不在最终的jar中。

将依赖项复制到特定目录

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy-dependencies</id><phase>prepare-package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory></configuration></execution></executions></plugin>

使JAR文件可执行和类路径感知

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><manifest><addClasspath>true</addClasspath><classpathPrefix>${project.build.finalName}.lib/</classpathPrefix><mainClass>${fully.qualified.main.class}</mainClass></manifest></archive></configuration></plugin>

此时,JAR文件实际上可以使用外部类路径元素执行。

java -jar target/${project.build.finalName}.jar

创建可部署的档案

JAR文件只能在兄弟...lib/目录下执行。我们需要制作存档以与目录及其内容一起部署。

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-antrun-plugin</artifactId><executions><execution><id>antrun-archive</id><phase>package</phase><goals><goal>run</goal></goals><configuration><target><property name="final.name" value="${project.build.directory}/${project.build.finalName}"/><property name="archive.includes" value="${project.build.finalName}.${project.packaging} ${project.build.finalName}.lib/*"/><property name="tar.destfile" value="${final.name}.tar"/><zip basedir="${project.build.directory}" destfile="${final.name}.zip" includes="${archive.includes}" /><tar basedir="${project.build.directory}" destfile="${tar.destfile}" includes="${archive.includes}" /><gzip src="${tar.destfile}" destfile="${tar.destfile}.gz" /><bzip2 src="${tar.destfile}" destfile="${tar.destfile}.bz2" /></target></configuration></execution></executions></plugin>

现在你有target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz),每个都包含jarlib/*


Apache Maven汇编插件

  • 优点
  • 缺点
    • 没有类重定位支持(如果需要类重定位,请使用maven-shad-plugin)。
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><executions><execution><phase>package</phase><goals><goal>single</goal></goals><configuration><archive><manifest><mainClass>${fully.qualified.main.class}</mainClass></manifest></archive><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration></execution></executions></plugin>

你有target/${project.bulid.finalName}-jar-with-dependencies.jar


Apache Maven Shade插件

  • 优点
  • 缺点
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><executions><execution><goals><goal>shade</goal></goals><configuration><shadedArtifactAttached>true</shadedArtifactAttached><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>${fully.qualified.main.class}</mainClass></transformer></transformers></configuration></execution></executions></plugin>

你有target/${project.build.finalName}-shaded.jar


onejar-maven插件

  • 优点
  • 缺点
    • 自2012年以来没有得到积极支持。
<plugin><!--groupId>org.dstovall</groupId--> <!-- not available on the central --><groupId>com.jolira</groupId><artifactId>onejar-maven-plugin</artifactId><executions><execution><configuration><mainClass>${fully.qualified.main.class}</mainClass><attachToBuild>true</attachToBuild><!-- https://code.google.com/p/onejar-maven-plugin/issues/detail?id=8 --><!-- classifier>onejar</classifier --><filename>${project.build.finalName}-onejar.${project.packaging}</filename></configuration><goals><goal>one-jar</goal></goals></execution></executions></plugin>

Spring Boot Maven插件

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><goal>repackage</goal></goals><configuration><classifier>spring-boot</classifier><mainClass>${fully.qualified.main.class}</mainClass></configuration></execution></executions></plugin>

你有target/${project.bulid.finalName}-spring-boot.jar

我尝试了这里投票最多的答案,并且能够让JAR文件可运行。但是程序无法正确运行。我不知道原因是什么。当我尝试从Eclipse运行时,我得到了不同的结果,但是当我从命令行运行JAR文件时,我得到了不同的结果(它因特定于程序的运行时错误而崩溃)。

我有一个和OP类似的需求,只是我的项目有太多的(Maven)依赖项。幸运的是,唯一对我有效的解决方案是使用Eclipse。这非常简单和直接。这不是OP的解决方案,但它是一个有类似需求的人的解决方案,但是有很多Maven依赖项,

  1. 只需右键单击您的项目文件夹(在Eclipse中)并选择导出

  2. 然后选择Java可运行JAR

  3. 您将被要求选择JAR文件的位置

  4. 最后,选择具有要运行的主要方法的类,并选择带有JAR文件的*包依赖项,然后单击完成

好的,这就是我的解决方案。我知道它没有使用pom.xml文件。但是我在NetBeans上编译和运行我的程序时遇到了问题,但是当我尝试Java-jar时失败了MyJarFile.jar.现在,我不完全理解Maven,我想这就是为什么在让NetBeans 8.0.2将我的JAR文件包含在库中以将它们放入JAR文件时遇到困难的原因。我在想我过去如何在Eclipse中使用没有Maven的JAR文件。

可以编译所有依赖项和插件的Maven。不是NetBeans。(如果您可以获得NetBeans并能够使用java. jar来执行此操作,请告诉我如何(^.^)v)

解决-Linux:通过打开终端。

然后

cd /MyRootDirectoryForMyProject

下一个

mvn org.apache.maven.plugins:maven-compiler-plugin:compile

下一个

mvn install

这将在目标目录中创建一个JAR文件。

MyJarFile-1.0-jar-with-dependencies.jar

现在

cd target

(您可能需要运行:chmod +x MyJarFile-1.0-jar-with-dependencies.jar

而最后

java -jar MyJarFile-1.0-jar-with-dependencies.jar

请看LifeyclePhaseNotFoundException

这是我找到的最好的方法:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.4</version><configuration><archive><manifest><addClasspath>true</addClasspath><mainClass>com.myDomain.etc.MainClassName</mainClass><classpathPrefix>dependency-jars/</classpathPrefix></manifest></archive></configuration></plugin>
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>2.5.1</version><executions><execution><id>copy-dependencies</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory></configuration></execution></executions></plugin>

使用此配置,所有依赖项都将位于/dependency-jars。我的应用程序没有Main类,只有上下文类,但我的一个依赖项确实有一个Main类(com.myDomain.etc.MainClassName)来启动JMX服务器,并接收startstop参数。所以有了这个,我就可以像这样启动我的应用程序:

java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start

这篇博文展示了另一种结合maven-jar和maven-汇编插件的方法。使用博文中的程序集配置XML文件,还可以控制依赖项是被扩展还是被收集在文件夹中并由清单中的类路径条目引用:

理想的解决方案是将jar包含在lib文件夹中,主jar的manifest.mf文件包含类路径中的所有jar。

这里描述的是:使用Maven执行具有依赖JAR文件的可执行JAR文件

我仔细检查了这些响应中的每一个,希望制作一个包含所有依赖项的胖可执行JAR文件,但没有一个正常工作。答案是阴影插件,它非常简单明了。

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>2.3</version>
<executions><!-- Run shade goal on package phase --><execution><phase>package</phase><goals><goal>shade</goal></goals>
<configuration><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>path.to.MainClass</mainClass></transformer></transformers></configuration></execution></executions>
</plugin>

请注意,您的依赖项需要具有编译或运行时范围才能正常工作。

这个例子来自mkyong.com

这也可以是一个选项。您将能够构建您的JAR文件。

<build><plugins><plugin><!-- Build an executable JAR --><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.4</version><configuration><archive><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><mainClass>WordListDriver</mainClass></manifest></archive></configuration></plugin></plugins></build>

我比较了这篇文章中提到的树插件。我生成了两个JAR文件和一个包含所有JAR文件的目录。我比较了结果,肯定maven-shad-plugin相关链接是最好的。

我的挑战是,我有多个Spring资源需要合并,以及jax-rs和JDBC服务。与maven-汇编-插件相比,它们都通过阴影插件正确合并。在这种情况下,Spring将失败,除非您将它们复制到自己的资源文件夹并手动合并一次。

两个插件都输出正确的依赖关系树。我有多个作用域,如测试、提供、编译等。两个插件都跳过了测试和提供。它们都产生了相同的清单,但我能够使用它们的转换器将许可证与阴影插件合并。使用maven-依赖-插件当然不会有这些问题,因为JAR文件没有被提取。但就像其他一些人指出的那样,您需要携带一个额外的文件才能正常工作。

这是pom.xml文件的片段:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy-dependencies</id><phase>prepare-package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/lib</outputDirectory><includeScope>compile</includeScope><excludeTransitive>true</excludeTransitive><overWriteReleases>false</overWriteReleases><overWriteSnapshots>false</overWriteSnapshots><overWriteIfNewer>true</overWriteIfNewer></configuration></execution></executions></plugin>
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>2.6</version><configuration><archive><manifest><addClasspath>true</addClasspath><mainClass>com.rbccm.itf.cdd.poller.landingzone.LandingZonePoller</mainClass></manifest></archive><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration><executions><execution><id>make-my-jar-with-dependencies</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin>
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>2.4.3</version><configuration><shadedArtifactAttached>false</shadedArtifactAttached><keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/services/javax.ws.rs.ext.Providers</resource></transformer><transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.factories</resource></transformer><transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.handlers</resource></transformer><transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.schemas</resource></transformer><transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.tooling</resource></transformer><transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/><transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer"></transformer></transformers></configuration><executions><execution><goals><goal>shade</goal></goals></execution></executions></plugin>

对于任何寻找从über JAR文件中排除特定依赖项的选项的人来说,这是一个适合我的解决方案:

<project...><dependencies><dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.11</artifactId><version>1.6.1</version><scope>provided</scope> <!--  <=============  --></dependency></dependencies>
<build><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifest><mainClass>...</mainClass></manifest></archive></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build></project>

它不是mvn组件安装插件介绍的配置,而是依赖项的属性。

要解决此问题,我们将使用Maven Assembly插件,该插件将创建JAR文件及其依赖项JAR文件到单个可执行JAR文件中。只需在pom.xml文件中添加以下插件配置。

<build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><configuration><archive><manifest><addClasspath>true</addClasspath><mainClass>com.your.package.MainClass</mainClass></manifest></archive><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration><executions><execution><id>make-my-jar-with-dependencies</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></pluginManagement></build>

完成此操作后,不要忘记使用以下命令运行Maven工具:

mvn clean compile assembly:single

Maven-创建一个JAR文件连同其依赖的JAR文件到一个可执行的JAR文件

已经有数百万个答案。如果您不需要将entryPoint添加到您的应用程序中,我想添加您不需要<mainClass>。例如,API可能不一定有main方法。

Maven插件配置

  <build><finalName>log-enrichment</finalName><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration></plugin></plugins></build>

构建

mvn clean compile assembly:single

验证

ll target/total 35100drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ./drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ../drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 archive-tmp/drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 classes/drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-sources/drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-test-sources/-rwxrwx--- 1 root vboxsf 35929841 Sep 29 16:10 log-enrichment-jar-with-dependencies.jar*drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 maven-status/

添加到文件pom.xml

<dependency><groupId>com.jolira</groupId><artifactId>onejar-maven-plugin</artifactId><version>1.4.4</version></dependency>

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

就是这样。接下来,mvn包还将额外创建一个胖JAR,包括所有依赖JAR文件。

您可以使用maven-Shade插件构建一个über JAR文件,如下所示:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><executions><execution><phase>package</phase><goals><goal>shade</goal></goals></execution></executions></plugin>
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>2.4.1</version><configuration><!-- get all project dependencies --><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration><executions><execution><id>make-assembly</id><!-- bind to the packaging phase --><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build>

我想将我的Spring应用程序(使用Apereo Foundation的CAS客户端)迁移到Spring Boot 1.5。我遇到了许多问题,例如:

目标/cas-client-web.jar中没有主清单属性

我尝试创建一个包含所有依赖项的唯一JAR文件。在Internet上搜索后,我能够使用以下行来完成它:

<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>
<plugin><artifactId>maven-assembly-plugin</artifactId><executions><execution><phase>package</phase><goals><goal>single</goal></goals></execution></executions><configuration><archive><manifest><addClasspath>true</addClasspath><mainClass>${start-class}</mainClass></manifest></archive><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration></plugin>

起始类是我的主类:

<properties><java.version>1.8</java.version><start-class>com.test.Application</start-class></properties>

我的申请方式是:

package com.test;
import java.util.Arrays;
import com.test.TestProperties;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.Bean;
@SpringBootApplication@EnableAutoConfiguration@EnableConfigurationProperties({TestProperties.class})public class Application {
public static void main(String[] args) {SpringApplication.run(Application.class, args);}
@Beanpublic CommandLineRunner commandLineRunner(ApplicationContext ctx) {return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();Arrays.sort(beanNames);for (String beanName : beanNames) {System.out.println(beanName);}};}
}

我尝试了多种解决方案,但这种解决方案在我们想要创建一个不可执行的胖JAR文件的场景中工作得很好,其中包含外部系统的所有内部依赖项,这些依赖项以前没有相关性。测试了一个生产场景。

将其包含在pom.xml文件中:

<?xml version="1.0" encoding="UTF-8"?><build><sourceDirectory>src</sourceDirectory><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration></plugin></plugins></build>

运行以构建胖JAR文件的命令:

mvn assembly:assembly

用途:

mvn clean install -U dependency:copy-dependencies

. jar文件将在名为“目标”的文件夹中生成,与“src”文件夹位于同一根目录中。