我想将我的项目打包在一个可执行的JAR中进行分发.
如何将所有依赖JAR的Maven项目打包到我的输出JAR中?
maven-assembly-plugin
fully.qualified.MainClass
jar-with-dependencies
你运行它
mvn clean compile assembly:single
应该在汇编之前添加编译目标:单个或者不包括您自己项目中的代码.
在评论中查看更多详情.
通常,此目标与构建阶段相关联,以自动执行.这可确保在执行mvn install
或执行部署/发布时构建JAR .
maven-assembly-plugin
fully.qualified.MainClass
jar-with-dependencies
make-assembly
package
single
您可以使用dependency-plugin在包阶段之前在单独的目录中生成所有依赖项,然后将其包含在清单的类路径中:
org.apache.maven.plugins
maven-dependency-plugin
copy-dependencies
prepare-package
copy-dependencies
${project.build.directory}/lib
false
false
true
org.apache.maven.plugins
maven-jar-plugin
true
lib/
theMainClass
或者使用${project.build.directory}/classes/lib
OutputDirectory将所有jar文件集成到主jar中,但是您需要添加自定义类加载代码来加载jar.
我在博客上写了一些不同的方法来做到这一点.
请参阅使用Apache Maven的可执行jar(WordPress)
或者可执行jar-with-maven-example(GitHub)
这些优点和缺点由Stephan提供.
优点
缺点
依赖性不在最后一个罐子里.
org.apache.maven.plugins
maven-dependency-plugin
copy-dependencies
prepare-package
copy-dependencies
${project.build.directory}/${project.build.finalName}.lib
org.apache.maven.plugins
maven-jar-plugin
true
${project.build.finalName}.lib/
${fully.qualified.main.class}
此时,jar
实际上可以使用外部类路径元素执行.
$ java -jar target/${project.build.finalName}.jar
该jar
文件只能与兄弟...lib/
目录一起执行.我们需要使用目录及其内容来部署存档.
org.apache.maven.plugins maven-antrun-plugin antrun-archive package run
现在你有target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
每个包含jar
和lib/*
.
优点
缺点
没有类重定位支持(如果需要类重定位,请使用maven-shade-plugin).
org.apache.maven.plugins
maven-assembly-plugin
package
single
${fully.qualified.main.class}
jar-with-dependencies
你有target/${project.bulid.finalName}-jar-with-dependencies.jar
.
优点
缺点
org.apache.maven.plugins
maven-shade-plugin
shade
true
${fully.qualified.main.class}
你有target/${project.build.finalName}-shaded.jar
.
优点
缺点
自2012年以来未得到积极支持
com.jolira
onejar-maven-plugin
${fully.qualified.main.class}
true
${project.build.finalName}-onejar.${project.packaging}
one-jar
优点
缺点
添加潜在的不必要的Spring和Spring Boot相关类.
org.springframework.boot
spring-boot-maven-plugin
repackage
spring-boot
${fully.qualified.main.class}
你有target/${project.bulid.finalName}-spring-boot.jar
.
采取未答复的答案并重新格式化,我们有:
org.apache.maven.plugins
maven-jar-plugin
true
fully.qualified.MainClass
maven-assembly-plugin
jar-with-dependencies
接下来,我建议将其作为构建的自然部分,而不是明确调用.要使其成为构建中不可或缺的一部分,请将此插件添加到您的插件pom.xml
并将其绑定到package
生命周期事件.但是,assembly:single
如果将它放在pom.xml中,则需要调用目标,而如果从命令行手动执行它,则调用'assembly:assembly'.
[...]
maven-assembly-plugin
true
fully.qualified.MainClass
jar-with-dependencies
make-my-jar-with-dependencies
package
single
[...]
[...]
使用maven-shade-plugin将所有依赖项打包到一个超级jar中.它还可以用于通过指定主类来构建可执行jar.在尝试使用maven-assembly和maven-jar之后,我发现这个插件最适合我的需求.
我发现这个插件特别有用,因为它合并了特定文件的内容而不是覆盖它们.当资源文件在jar中具有相同的名称并且插件尝试打包所有资源文件时,需要这样做
见下面的例子
org.apache.maven.plugins maven-shade-plugin 1.4 package shade bouncycastle:bcprov-jdk15 com.main.MyMainClass properties.properties applicationContext.xml META-INF/cxf/cxf.extension META-INF/cxf/bus-extensions.xml
长期使用maven程序集插件,但我无法找到问题的解决方案"already added, skipping"
.现在,我正在使用另一个插件 - onejar-maven-plugin.下面的例子(mvn package
构建jar):
org.dstovall onejar-maven-plugin 1.3.0 com.company.MainClass one-jar
您需要为该插件添加存储库:
onejar-maven-plugin.googlecode.com http://onejar-maven-plugin.googlecode.com/svn/mavenrepo
您可以使用maven-dependency-plugin,但问题是如何创建可执行JAR.要做到这一点,需要对Matthew Franglen的响应进行以下更改(顺便说一下,使用依赖插件从清理目标开始时需要更长时间才能构建):
maven-jar-plugin fully.qualified.MainClass maven-dependency-plugin unpack-dependencies package unpack-dependencies ${basedir}/target/dependency
如果你真的想在你的单个结果JAR中重新打包其他JAR内容,另一个选择是Maven Assembly插件.它解压缩然后将所有内容重新打包到目录中
.然后你会有第二遍将它构建成一个巨大的JAR.
另一个选择是OneJar插件.这将一步完成上述重新打包操作.
您可以将以下内容添加到pom.xml:
install maven-compiler-plugin 2.3.2 1.6 org.apache.maven.plugins maven-jar-plugin 2.3.1 true com.mycompany.package.MainClass maven-assembly-plugin jar-with-dependencies com.mycompany.package.MainClass make-my-jar-with-dependencies package single
之后,您必须通过控制台切换到pom.xml所在的目录.然后你必须执行mvn程序集:单个然后你的可执行JAR文件将有希望构建.使用cd ./target切换到输出(目标)目录并使用类似于java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar的命令启动jar 时,可以检查它.
我用Apache Maven 3.0.3测试了这个.
我经历了这些响应中的每一个,希望制作一个包含所有依赖项的胖可执行jar,但它们都没有正常工作.答案是阴影插件,它非常简单直接.
org.apache.maven.plugins maven-shade-plugin 2.3 package shade path.to.MainClass
请注意,您的依赖项需要具有编译或运行时范围才能使其正常工作.
这个例子来自mkyong.com
你可以结合maven-shade-plugin
和maven-jar-plugin
.
将maven-shade-plugin
您的类和所有依赖项打包在一个jar文件中.
配置maven-jar-plugin
以指定可执行jar的主类(请参阅设置类路径,"使Jar可执行文件"一章).
示例POM配置maven-jar-plugin
:
org.apache.maven.plugins maven-jar-plugin 2.3.2 true com.example.MyMainClass
最后通过调用创建可执行jar:
mvn clean package shade:shade
您可以使用maven-shade插件来构建如下所示的超级jar
org.apache.maven.plugins maven-shade-plugin package shade
Ken Liu在我看来是正确的.maven依赖插件允许您扩展所有依赖项,然后您可以将其视为资源.这允许您将它们包含在主工件中.使用程序集插件会创建一个难以修改的辅助工件 - 在我的情况下,我想添加自定义清单条目.我的pom最终成了:
... ... ... org.apache.maven.plugins maven-dependency-plugin unpack-dependencies package unpack-dependencies ${basedir}/target/dependency /
它应该是这样的:
maven-dependency-plugin unpack-dependencies generate-resources unpack-dependencies
解包必须处于生成资源阶段,因为如果处于打包阶段,则不会将其作为资源包含在内.尝试清洁包装,你会看到.
这是我们在Credit Karma使用的Maven的可执行jar插件.它创建了一个jar罐,其中包含一个能够从嵌套jar加载类的类加载器.这允许您在dev和prod中具有相同的类路径,并且仍将所有类保留在单个签名的jar文件中.
https://github.com/creditkarma/maven-exec-jar-plugin
这里有一篇博客文章,详细介绍了插件及其制作原因:https: //engineering.creditkarma.com/general-engineering/new-executable-jar-plugin-available-apache-maven/
使用onejar插件将其构建为一个可执行jar文件,该文件将所有依赖jar包装在其中.这解决了我的问题,与此类似.当使用程序集插件时,它将所有依赖jar解压缩到源文件夹中并将它们重新打包为jar,它已经覆盖了我在代码中具有相同类名的所有类似实现.onejar在这里是一个简单的解决方案.
使用maven-assembly-plugin-2.2.1查找共享程序集文件的问题?
尝试使用descriptorId配置参数而不是descriptors/descriptor或descriptorRefs/descriptorRef参数.
他们都没有做你需要的:在classpath上查找文件.当然,您需要在maven-assembly-plugin的类路径中添加共享程序集所在的包(请参阅下文).如果您使用的是Maven 2.x(而不是Maven 3.x),则可能需要在pluginManagement部分的最顶级父pom.xml中添加此依赖项.
有关详细信息,请参阅此
类:org.apache.maven.plugin.assembly.io.DefaultAssemblyReader
例:
maven-assembly-plugin 2.2.1 make-assembly package single assembly-zip-for-wid cz.ness.ct.ip.assemblies TEST_SharedAssemblyDescriptor 1.0.0-SNAPSHOT
我不会像其他人之前已经做过的那样直接回答这个问题,但我真的很想知道将所有依赖项嵌入项目的jar本身是否是一个好主意.
我看到了重点(易于部署/使用)但它取决于你的项目的用例(并且可能有替代方案(见下文)).
如果你完全独立使用它,为什么不.
但是如果你在其他环境中使用你的项目(比如在webapp中,或者放在其他jar所在的文件夹中),你的类路径中可能会有jar副本(文件夹中的那些,jar中的那个).也许不是出价协议,但我通常会避免这种情况.
一个很好的选择:
将您的应用程序部署为.zip/.war:存档包含项目的jar和所有相关的jar;
使用动态类加载器机制(参见Spring,或者您可以轻松地自己完成),以获得项目的单个入口点(单个类开始 - 参见另一个答案的Manifest机制),它将(动态)添加到当前类路径所有其他需要的罐子.
像这样,最后只有一个清单和一个"特殊的动态类加载器主",你可以用以下内容启动你的项目:
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
为了解决此问题,我们将使用Maven程序集插件,该插件将JAR及其依赖项JAR创建到单个可执行JAR文件中。只需在pom.xml文件中添加以下插件配置即可。
org.apache.maven.plugins maven-assembly-plugin true com.your.package.MainClass jar-with-dependencies make-my-jar-with-dependencies package single
完成此操作后,请不要忘记使用以下命令运行MAVEN工具mvn clean compile assembly:single
http://jkoder.com/maven-creating-a-jar-together-with-its-dependency-jars-into-a-single-executable-jar-file/