Maven打包所有依赖到一个可执行jar中

Posted 拾年一剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Maven打包所有依赖到一个可执行jar中相关的知识,希望对你有一定的参考价值。

文章目录

需求

普通的Maven Java项目(非Springboot项目),需要打包成一个jar包(包含所有的第三方依赖jar包),能够放在服务器上单独运行。

遇到的问题

找不到主类

大家都知道,如果使用常见的maven-jar-plugin打包,只能将自己项目里的源码编译打包,不会包含第三方的jar包。

如果该项目没有第三方依赖包,则可以通过maven-jar-plugin打包,直接执行打好的jar包(java -jar xxx.jar),可能会遇到找不到主类的情况,可以通过下面的方式解决:指定主类

<plugin>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>com.xxx.AppMain</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

注意:

META-INF文件夹是MANIFEST.MF文件的主页。 此文件包含有关JAR内容的元数据。
JAR包中的/META-INF/MANIFEST.MF元数据文件必须包含Main-Class(主类)信息。(工程里的src/META-INF/MANIFEST.MF)
项目所有的依赖都必须在Classpath中,其可以通过 MANIFEST.MF 指定或者隐式设置。

打包时没有包含第三方依赖

如果该项目有第三方依赖包,通过上面的方式打包,是不会包含第三方依赖的,直接运行生成的jar包会出错(相关依赖不存在)。
想要打包时包含第三方依赖,又可以分两种情况:

情况1

打包成可执行jar文件,但是将所有依赖(包括外部依赖)单独打包到另外一个指定文件夹下,通过指定Class-Path的方式关联。

  1. 打包依赖到指定文件夹
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>$project.build.directory/lib</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

关于Maven dependency plugin可以参考我的另外一篇博客,有详细介绍:

Maven dependency plugin使用

  1. 指定启动入口,并关联依赖
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <!-- 是否绑定依赖,将外部jar包依赖加入到classPath中 -->
                <addClasspath>true</addClasspath>
                <!-- 依赖前缀,与之前设置的文件夹路径要匹配 -->
                <classpathPrefix>lib/</classpathPrefix>
                <!-- 主函数的入口 -->
                <mainClass>com.xxx.AppMain</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

配置好后,可以通过下面的命令编译打包:
mvn clean pacakge -DskipTests=true

注意,复杂情况下,classpath需要在运行时指定,如 java -cp …

情况2

将整个工程打成一个可执行jar包,包含所有的依赖。

需要通过maven-assembly-plugin插件来打包,可以实现该需求。

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</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>
                <archive>
                    <manifest>
                        <mainClass>com.xxx.AppMain</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

配置好后,可以通过下面的命令编译打包:
mvn assembly:assembly
执行成功后会在target文件夹下多出一个以-jar-with-dependencies结尾的jar包. 这个jar包就包含了项目所依赖的所有jar的class

扩展问题

不希望依赖的jar包变成class

可以通过修改插件的配置做到

  1. 在本地maven仓库里找到maven-assembly-plugin
cd ~/.m2/repository/org/apache/maven/plugins/maven-assembly-plugin/
  1. 进入打包时运行使用的版本里,如2.2-beta-5;
  2. 解压maven-assembly-plugin-2.2-beta-5.jar;
  3. 进入解压好的文件夹找到assemblies\\jar-with-dependencies.xml,
    把里面的UNPACK改成FALSE,保存即可;
  4. 还原解压后的文件为jar包
    例如,在~/.m2/repository/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5 路径里,执行下面的命令
jar cvfm maven-assembly-plugin-2.2-beta-5.jar maven-assembly-plugin-2.2-beta-5/META-INF/MANIFEST.MF -C maven-assembly-plugin-2.2-beta-5 .
  1. 再次使用mvn assembly:assembly打包,编译好的以-jar-with-dependencies结尾的jar包. 这个jar包就包含了项目所依赖的所有jar文件,不再是class;

项目里多个主类,如何动态指定

可以通过自定义property属性,在执行maven命令时,动态指定来实现,配置如下:

例如,main.class 则为自定义的;

<properties>
    <main.class>com.xxx.AppMain</main.class>
</properties>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</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>
                <archive>
                    <manifest>
                        <mainClass>$main.class</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

运行maven命令时,动态指定:

mvn -Dmain.class=com.xxx.AppMain2 assembly:assembly

Maven学习Maven打包生成普通jar包可运行jar包包含所有依赖的jar包

http://blog.csdn.net/u013177446/article/details/54134394

******************************************************

 

使用maven构建工具可以将工程打包生成普通的jar包、可运行的jar包,也可以将所有依赖一起打包生成jar;

一、普通的jar包

普通的jar包只包含工程源码编译出的class文件以及资源文件,而不包含任何依赖;同时还包括pom文件,说明该包的依赖信息;
在工程pom文件下这样写,可生成普通的jar包:

<packaging>jar<packaging>

或者,不写,因为packaging默认打包类型为jar

二、包含所有依赖的jar包

普通的jar包,只在pom文件中包含依赖信息,而不包含真正的依赖,但同时maven也可以打包生成包含所有依赖的jar文件,可参考本博客文章 Maven打包生成包含所有依赖的jar包

三、可运行jar包

可运行的jar包,除包含工程源码编译结果外,还包括所有依赖,可利用java -jar 命令直接运行。(所有的依赖jar包直接变成了class)
使用maven生成可运行jar包,可参考本博客文章 maven打包生成可执行jar文件



以上是关于Maven打包所有依赖到一个可执行jar中的主要内容,如果未能解决你的问题,请参考以下文章

通过 maven-assembly-plugin 打包在 jar 中包含 spring xml

如何把一个jar包打包到本地maven仓库

Maven引入本地依赖Jar到可执行Jar包中

Maven项目打Jar包,如何添加依赖

maven项目打包插件:将maven项目打包成一个可执行的jar(瘦jar)

Maven学习Maven打包生成普通jar包可运行jar包包含所有依赖的jar包