How can I create an executable JAR with dependencies using Maven?
我想将我的项目打包到一个可执行的jar中进行分发。
如何将Maven项目包中的所有依赖jar打包到输出jar中?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <build> <plugins> <plugin> maven-assembly-plugin</artifactId> <configuration> <manifest> <mainClass>fully.qualified.MainClass</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> </build> |
和你一起跑
1 | mvn clean compile assembly:single |
编译目标应该在组装之前添加:单个或其他情况下不包括您自己项目上的代码。
请参阅评论中的更多详细信息。
通常,此目标与要自动执行的构建阶段相关联。这样可以确保在执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <plugin> maven-assembly-plugin</artifactId> <configuration> <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> |
在包阶段之前,可以使用依赖插件在单独的目录中生成所有依赖项,然后将其包含在清单的类路径中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <plugin> <groupId>org.apache.maven.plugins</groupId> 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> maven-jar-plugin</artifactId> <configuration> <manifest> true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>theMainClass</mainClass> </manifest> </archive> </configuration> </plugin> |
或者使用
我在博客上介绍了一些不同的方法。
请参阅带有ApacheMaven(WordPress)的可执行JAR
或带有maven示例(github)的可执行jar
笔记这些利弊都是斯蒂芬提供的。
用于手动部署- 赞成的意见
- 欺骗
- 依赖项在最终的JAR中。
将依赖项复制到特定目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <plugin> <groupId>org.apache.maven.plugins</groupId> 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可执行并知道类路径
1 2 3 4 5 6 7 8 9 10 11 12 13 | <plugin> <groupId>org.apache.maven.plugins</groupId> maven-jar-plugin</artifactId> <configuration> <manifest> true</addClasspath> <classpathPrefix>${project.build.finalName}.lib/</classpathPrefix> <mainClass>${fully.qualified.main.class}</mainClass> </manifest> </archive> </configuration> </plugin> |
此时,
1 | $ java -jar target/${project.build.finalName}.jar |
创建可部署的存档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <plugin> <groupId>org.apache.maven.plugins</groupId> 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> |
现在你有了
- 赞成的意见
- 欺骗
- 没有类重定位支持(如果需要类重定位,请使用maven shade插件)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <plugin> <groupId>org.apache.maven.plugins</groupId> maven-assembly-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <manifest> <mainClass>${fully.qualified.main.class}</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </execution> </executions> </plugin> |
你有
- 赞成的意见
- 欺骗
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <plugin> <groupId>org.apache.maven.plugins</groupId> 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> |
你有一辆车。
Onejar Maven插件- 赞成的意见
- 欺骗
- 自2012年以来未得到积极支持。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <plugin> <!--groupId>org.dstovall</groupId--> <!-- not available on the central --> <groupId>com.jolira</groupId> onejar-maven-plugin</artifactId> <executions> <execution> <configuration> <mainClass>${fully.qualified.main.class}</mainClass> 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引导Maven插件
- 赞成的意见
- 欺骗
- 添加潜在的与Spring和Spring引导相关的类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <plugin> <groupId>org.springframework.boot</groupId> 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> |
你有埃多克斯1〔8〕。
接受未回答的答案并重新格式化,我们有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> maven-jar-plugin</artifactId> <configuration> <manifest> true</addClasspath> <mainClass>fully.qualified.MainClass</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> </build> |
接下来,我建议将其作为构建的自然部分,而不是显式调用。要使其成为构建的组成部分,请将此插件添加到您的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <project> [...] <build> <plugins> <plugin> maven-assembly-plugin</artifactId> <configuration> <manifest> 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> |
使用maven shade插件将所有依赖项打包到一个uber jar中。它还可以通过指定主类来构建可执行JAR。在尝试使用maven程序集和maven jar之后,我发现这个插件最适合我的需要。
我发现这个插件特别有用,因为它合并了特定文件的内容,而不是覆盖它们。当JAR中有相同名称的资源文件,并且插件试图打包所有资源文件时,需要这样做。
见下面的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <plugins> <!-- This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies. --> <plugin> <groupId>org.apache.maven.plugins</groupId> maven-shade-plugin</artifactId> <version>1.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <!-- signed jars--> <excludes> <exclude>bouncycastle:bcprov-jdk15</exclude> </excludes> </artifactSet> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <!-- Main class --> <mainClass>com.main.MyMainClass</mainClass> </transformer> <!-- Use resource transformers to prevent file overwrites --> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>properties.properties</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer"> <resource>applicationContext.xml</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/cxf/cxf.extension</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer"> <resource>META-INF/cxf/bus-extensions.xml</resource> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> |
长期使用Maven程序集插件,但我找不到解决
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <plugin> <groupId>org.dstovall</groupId> 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> |
您需要为该插件添加存储库:
1 2 3 4 5 6 | <pluginRepositories> <pluginRepository> <id>onejar-maven-plugin.googlecode.com</id> <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url> </pluginRepository> </pluginRepositories> |
您可以使用Maven依赖插件,但问题是如何创建可执行JAR。要做到这一点,需要对Matthew Franglen的响应进行以下修改(顺便说一句,从干净的目标开始使用依赖插件需要更长的时间来构建):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <build> <plugins> <plugin> maven-jar-plugin</artifactId> <configuration> <manifest> <mainClass>fully.qualified.MainClass</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> 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中的其他JAR内容,另一个选项是Maven程序集插件。它解包,然后通过
另一个选项是Onejar插件。这将在一个步骤中执行上述重新打包操作。
您可以将以下内容添加到pom.xml中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <build> <defaultGoal>install</defaultGoal> <plugins> <plugin> 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> maven-jar-plugin</artifactId> <version>2.3.1</version> <configuration> <manifest> true</addClasspath> <mainClass>com.mycompany.package.MainClass</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <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程序集:single,然后您的具有依赖性的可执行jar文件将有望构建。您可以在切换到CD/.Target的输出(目标)目录时检查它,并启动一个类似于Java-JavaMavePark1.1-SnAPHOTH-JAR-WEXCENCENCI.jar的命令。
我用ApacheMaven 3.0.3测试了这个。
我仔细检查了所有这些响应,希望生成一个包含所有依赖项的胖的可执行jar,但没有一个能够正常工作。答案是shade插件,它非常简单和简单。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <plugin> <groupId>org.apache.maven.plugins</groupId> 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
你可以把
maven-shade-plugin 将类和所有依赖项打包到一个JAR文件中。- 配置
maven-jar-plugin 以指定可执行jar的主要类(请参见设置类路径,章节"使jar可执行")。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <plugin> <groupId>org.apache.maven.plugins</groupId> maven-jar-plugin</artifactId> <version>2.3.2</version> <configuration> <manifest> true</addClasspath> <mainClass>com.example.MyMainClass</mainClass> </manifest> </archive> </configuration> </plugin> |
最后通过调用以下命令创建可执行JAR:
1 | mvn clean package shade:shade |
您可以使用maven-shade插件构建一个如下所示的超级jar
1 2 3 4 5 6 7 8 9 10 11 12 | <plugin> <groupId>org.apache.maven.plugins</groupId> maven-shade-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> |
这里有一个maven的可执行jar插件,我们在credit karma中使用。它创建了一个JAR JAR,其中的类加载器能够从嵌套JAR中加载类。这允许您在dev和prod中拥有相同的类路径,并且仍然将所有类保存在一个签名的jar文件中。
https://github.com/creditkarma/maven-exec-jar-plugin
下面是一篇博客文章,详细介绍了这个插件以及我们为什么创建它:https://engineering.creditkama.com/general-engineering/new-executable-jar-plugin-available-apache-maven/
刘肯在我看来是对的。Maven依赖插件允许您扩展所有依赖项,然后可以将其视为资源。这允许您将它们包含在主工件中。程序集插件的使用创建了一个二级工件,这很难修改——在我的例子中,我想添加自定义清单条目。我的POM结果是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> 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> |
应该是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 | <plugin> maven-dependency-plugin</artifactId> <executions> <execution> <id>unpack-dependencies</id> <phase>generate-resources</phase> <goals> <goal>unpack-dependencies</goal> </goals> </execution> </executions> </plugin> |
解包必须处于"生成资源"阶段,因为如果处于包阶段,则不会作为资源包含在内。试试干净的包装,你会看到的。
使用Onejar插件将其构建为一个可执行的jar文件,其中打包了其中的所有依赖jar。这解决了我类似的问题。当使用程序集插件时,它将所有依赖jar解包到源文件夹中,并将它们重新打包为jar,它重写了我在代码中拥有相同类名的所有类似实现。Onejar是一个简单的解决方案。
使用maven-assembly-plugin-2.2.1定位共享程序集文件时出现问题?
尝试使用DescriptorID配置参数而不是描述符/描述符或DescriptorRef/DescriptorRef参数。
它们都不做您需要的:在类路径上查找文件。当然,您需要添加共享程序集驻留在Maven程序集插件的类路径上的包(见下文)。如果您使用的是maven 2.x(而不是maven 3.x),那么您可能需要在pluginmanagement部分的最上层pom.xml中添加这个依赖项。
有关详细信息,请参阅此。
类:org.apache.maven.plugin.assembly.io.defaultassemblyreader
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <!-- Use the assembly plugin to create a zip file of all our dependencies. --> <plugin> 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> TEST_SharedAssemblyDescriptor</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> </dependencies> </plugin> |
我不会像其他人以前那样直接回答这个问题,但我真的想知道将所有依赖项嵌入到项目的JAR中是否是一个好主意。
我明白这一点(易于部署/使用),但这取决于项目的用例(可能还有其他选择(见下文))。
如果你完全独立使用它,为什么不呢?
但是如果您在其他环境中使用您的项目(比如在webapp中,或者放在其他jar所在的文件夹中),您的类路径中可能有jar副本(文件夹中的,jar中的)。也许不是出价协议,但我通常避免这样做。
一个好的选择:
- 将应用程序部署为.zip/.war:存档包含项目的jar和所有相关jar;
- 使用动态类加载器机制(请参阅Spring,或者您自己也可以很容易地做到这一点)来拥有项目的单个入口点(要启动的单个类-请参阅另一个答案上的清单机制),它将(动态地)添加到当前类路径中所有其他需要的jar。
像这样,在最后只有一个清单和一个"特殊的动态类加载器主目录"的情况下,您可以用以下方法开始您的项目:
1 | java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass |
为了解决这个问题,我们将使用Maven程序集插件,它将创建JAR及其依赖JAR到单个可执行JAR文件中。只需在pom.xml文件中添加以下插件配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> maven-assembly-plugin</artifactId> <configuration> <manifest> 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- Creating a Jar together with its dependency Jars into a single executable Jar file
如果您想从命令行本身获取if。只需从项目路径运行以下命令
MVN程序集:程序集
您也可以使用这个插件,它非常好,我使用它来打包jars http://sonatype.github.io/jarjar-maven-plug in/
对我有用的是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <plugin> 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> maven-jar-plugin</artifactId> <executions> <execution> <id>unpack-dependencies</id> <phase>package</phase> </execution> </executions> <configuration> <manifest> true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>SimpleKeyLogger</mainClass> </manifest> </archive> </configuration> </plugin> |
我有一个特别的案例,因为我的依赖是系统一:
1 2 3 4 5 | <dependency> .. <scope>system</scope> <systemPath>${project.basedir}/lib/myjar.jar</systemPath> </dependency> |
我已经更改了@user189057提供的代码,更改内容如下:1)maven依赖插件在"准备包"阶段执行2)我将解包类直接提取到"目标/类"
我在这里试过投票最多的答案,并能让罐子运行。但是程序没有正确运行。我不知道是什么原因。当我尝试从
我有一个与OP类似的需求,只是我的项目有太多(maven)依赖项。幸运的是,唯一对我有用的解决方案是使用
1)只需右键单击项目文件夹(在Eclipse中),然后选择
2)然后选择
3)将要求您选择JAR文件的位置。
4)最后,选择要运行的主方法的类,选择
这是我找到的最好方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <plugin> <groupId>org.apache.maven.plugins</groupId> maven-jar-plugin</artifactId> <version>2.4</version> <configuration> <manifest> true</addClasspath> <mainClass>com.myDomain.etc.MainClassName</mainClass> <classpathPrefix>dependency-jars/</classpathPrefix> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> 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> |
使用此配置,所有依赖项都将位于
1 | java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start |
我等着这对你们大家都有用。
我比较了本文中提到的树插件。我生成了2个jar和一个包含所有jar的目录。我比较了结果,肯定maven shade插件是最好的。我面临的挑战是,我有多个需要合并的Spring资源,以及JAX RS和JDBC服务。与Maven程序集插件相比,shade插件正确地合并了所有这些插件。在这种情况下,除非您将它们复制到自己的资源文件夹并手动合并一次,否则Spring将失败。两个插件都输出正确的依赖树。我有多个作用域,比如test、provide、compile等,这两个插件都跳过了测试和提供的作用域。它们都生成了相同的清单,但我可以使用它们的转换器用shade插件合并许可证。对于Maven依赖插件,当然您没有这些问题,因为JAR没有被提取出来。但是像其他人指出的那样,你需要携带一个额外的文件才能正常工作。下面是pom.xml的一个片段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | <plugin> <groupId>org.apache.maven.plugins</groupId> 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> maven-assembly-plugin</artifactId> <version>2.6</version> <configuration> <manifest> 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> 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> |
对于任何想从uber jar中排除特定依赖项的人来说,这是一个适用于我的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <project...> <dependencies> <dependency> <groupId>org.apache.spark</groupId> spark-core_2.11</artifactId> <version>1.6.1</version> <scope>provided</scope> <============= </dependency> </dependencies> <build> <plugins> <plugin> maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <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程序集插件的配置,而是依赖项的属性。
已经有数百万个答案了,我想补充一下,如果您不需要向应用程序添加入口点,那么您不需要
1 2 3 4 5 6 7 8 9 10 11 12 13 | <build> <finalName>log-enrichment</finalName> <plugins> <plugin> maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> </build> |
建造
1 | mvn clean compile assembly:single |
验证
1 2 3 4 5 6 7 8 9 10 | ll target/ total 35100 drwxrwx--- 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:
1 2 3 4 5 | <dependency> <groupId>com.jolira</groupId> onejar-maven-plugin</artifactId> <version>1.4.4</version> </dependency> |
和
1 2 3 4 5 6 7 8 9 10 11 12 | <plugin> <groupId>com.jolira</groupId> onejar-maven-plugin</artifactId> <version>1.4.4</version> <executions> <execution> <goals> <goal>one-jar</goal> </goals> </execution> </executions> </plugin> |
就是这样。下一个MVN包还将另外创建一个胖jar,包括所有依赖jar。
这也可以是一个选项,您将能够构建JAR文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <build> <plugins> <plugin> <!-- Build an executable JAR --> <groupId>org.apache.maven.plugins</groupId> maven-jar-plugin</artifactId> <version>2.4</version> <configuration> <manifest> true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>WordListDriver</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> |
Maven程序集插件对我很有用。我花了几个小时在Maven依赖插件上,但无法使它工作。主要原因是我必须在配置部分明确地定义工件项,正如文档中所描述的那样,工件项应该包括在内。这里有一个例子,当你想使用它时,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> 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> |
这个博客文章展示了结合maven jar和maven汇编插件的另一种方法。通过日志中的程序集配置XML,还可以控制是扩展依赖项,还是将依赖项收集到文件夹中并由清单中的类路径条目引用:
The ideal solution is to include the jars in a lib folder and the manifest.mf file of the main jar include all the jars in classpath.
这里正是这样描述的:https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/
好吧,这就是我的解决方案。我知道它没有使用pom.xml文件。但是我的程序编写和运行在NETBeBes上遇到了问题,但是当我尝试JavaJavaMyjARFIL.jar时,它失败了。现在,我不完全理解Maven,我认为这就是为什么让NetBeans 8.0.2将我的JAR文件包含在库中以将它们放入JAR文件时遇到困难的原因。我在想我以前是如何在Eclipse中使用没有Maven的JAR文件的。
Maven可以编译所有依赖项和插件。不是网豆。(如果你能得到NETBeOne,并且能够使用Java.jar来做这件事,请告诉我如何(^ ^)v)
[解决-Linux版]通过打开终端。
然后
1 | cd /MyRootDirectoryForMyProject |
接下来
1 | mvn org.apache.maven.plugins:maven-compiler-plugin:compile |
接下来
1 | mvn install |
这将在目标目录中创建JAR文件。
1 | MyJarFile-1.0-jar-with-dependencies.jar |
现在
1 | cd target |
(您可能需要运行:
最后
1 | java -jar MyJarFile-1.0-jar-with-dependencies.jar |
请看
https://cwiki.apache.org/confluence/display/maven/lifecyclephasenotfoundexception
我将把这个解决方案发布到其他几个有类似问题的页面上。希望我能让别人从一周的挫折中解脱出来。
请使用图片演示查看此答案https://stackoverflow.com/a/35359756/5678086,以创建包含所有依赖项的完整包。