如何通过maven打包可执行jar包[通俗易懂]

如何通过maven打包可执行jar包[通俗易懂]一、目的将代码打包成jar包有四种形式:1、只打包本项目的代码,不包括依赖的jar包,并且不可直接通过java-jarxxx.jar执行(应用场景:我们日常使用依赖的jar包)2、只打包本项目的代码,不包括依赖的jar包,并且可以直接通过java-jarxxx.jar执行(应用场景:执行时依赖的jar包存在在本jar包外部,减少jar体积)3、打包本项目的代码,同时将依赖的jar包解压后的文件复制到本jar包中,可以直接通过java-jarxxx.jar执行(应用场景:直接执行,

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

一、目的

介绍将代码打包成jar包的四种形式:

  1. 只打包本项目的代码,不包括依赖的jar包,并且不可直接通过java -jar xxx.jar执行(应用场景:我们日常使用依赖的jar包)
  2. 只打包本项目的代码,不包括依赖的jar包,并且可以直接通过java -jar xxx.jar执行(应用场景:执行时依赖的jar包存在在本jar包外部,减少jar体积)
  3. 打包本项目的代码,同时将依赖的jar包解压后的文件复制到本jar包中,可以直接通过java -jar xxx.jar执行(应用场景:直接执行,一个jar包即可搞定)
  4. 打包本项目的代码,同时将依赖的jar包直接复制到本jar包中,可以直接通过java -jar xxx.jar执行(应用场景:直接执行,一个jar包即可搞定)

PS:3和4的区别是,3在复制时可能不同的jar包中存在相同的资源文件,导致被覆盖掉,需要特殊处理。

接下来详细介绍这四种jar包的打包方式

二、打包不可执行jar包

我们日常通过maven依赖的jar包就是这种不可执行的jar包,这种包有两种打包方式

1、直接执行maven package命令,在target目录下xxx.jar即为我们需要的jar包

2、在pom.xml中配置如下内容,执行maven package命令,在target目录下xxx.jar即为我们需要的jar包

    <packaging>jar</packaging>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <!--生成的jar中,不要包含pom.xml和pom.properties这两个文件-->
                        <addMavenDescriptor>true</addMavenDescriptor>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

三、打包可执行jar包

        直接执行上一步打包的jar包时会提示:xxx.jar中没有主清单属性。原因是执行java -jar xxx.jar命令时,jvm不知道程序的main方法在哪个类里,所以需要我们打包的时候告知这个启动类的位置,也就是通过MAINFEST.MF来指定启动类的位置(当然也可以通过命令参数指定启动类:java -cp xxx.jar com.MainClass,其中com.MainClass为启动类的全名称)

打包时生成MAINFEST.MF文件,指定启动类的位置。其中com.MainClass为自己启动类的全名称

    <packaging>jar</packaging>   
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <!--生成的jar中,不要包含pom.xml和pom.properties这两个文件-->
                        <addMavenDescriptor>true</addMavenDescriptor>
                        <manifest>
                            <mainClass>com.MainClass</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

执行maven package命令,在target目录下xxx.jar即为我们需要的jar包,直接执行java -jar xxx.jar命令即可

四、打包可执行jar包(添加外部jar包中的类)

如果我们在我们的应用程序里依赖并使用了其他的jar包,比如json-lib

maven配置:

        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
        </dependency>

启动类:

    public static void main(String[] args) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("key","value");
        System.out.println(jsonObject);
    }

        这时候按照上一步的方式打包后,执行java -jar xxx.jar命令,会报java.lang.NoClassDefFoundError异常,原因是我们程序里依赖的json-lib.jar包并没有一并打包到jar包里,找不到对应的类。要解决这个问题,我们有两种办法,第一个是把json-lib.jar中的类打包的时候复制到我们的jar包中。第二个办法是直接把json-lib.jar打包到我们的jar包中,第二个办法下一步再介绍。

打包的时候将依赖的jar中的类复制到我们的jar包中:其中com.MainClass为自己启动类的全名称

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <transformers>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>com.MainClass</mainClass>
                        </transformer>
                    </transformers>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

执行maven package命令,打包后的jar包中包含所有依赖的外部jar包中类,如下图所示,xxx.jar是我们需要的jar包(另外一个original-xxx.jar包中不包含外部jar包中的类,和上一步打出的jar包一样):

如何通过maven打包可执行jar包[通俗易懂]

直接执行java -jar xxx.jar命令即可。

PS:使用这种直接复制类的方式会带来一个问题,就是不同jar包中如果存在多个资源文件,比如很多spring的jar包都含有META-INF/spring.handlers或者META-INF/spring.schemas文件,打包的时候如果存在n个相同资源文件(路径和名称都相同),则会丢失n-1的资源文件,对此场景我们可以使用合并功能,将这n个相同资源文件中的内容合并为一个资源文件(当前还有很多其他处理场景,详情参加:Apache Maven Shade Plugin – Resource Transformers)

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <transformers>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>com.MainClass</mainClass>
                        </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>
                    </transformers>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

五、打包可执行jar包(直接添加外部jar包)

上一步遇到的资源文件重复的问题也可以通过直接添加外部jar包来解决:其中com.MainClass为自己启动类的全名称

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.3.3.RELEASE</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.MainClass</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

执行maven package命令,打包后的jar包格式,依赖的jar包都直接放在lib目录下: 

如何通过maven打包可执行jar包[通俗易懂]

直接执行java -jar xxx.jar命令即可。

以上四种方式可以根据具体的业务场景选择不同的打包方式!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/186076.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • iphone android换机助手下载,换机助手IOS版下载 换机助手(微信文件手机搬家) for iphone v1.0.13 苹果手机版 下载-脚本之家…

    iphone android换机助手下载,换机助手IOS版下载 换机助手(微信文件手机搬家) for iphone v1.0.13 苹果手机版 下载-脚本之家…换机助手IOS版是一款适用于苹果手机端的微信文件手机搬家软件,能够有效的对微信文件进行管理,可以在两台手机之间建立连接文件传输,感兴趣的朋友快来下载使用吧。软件功能能够在平台上通过扫描功能,快速的将两台手机进行连接;在平台上可以进行文件的传输,快速将文件传输到另外一台手机上;系统会将平台上的微信文件快速的进行识别,显示在平台上;平台上的文件信息都会根据类型的不同进行有效的分类;线上就能进行文件等信…

    2022年5月16日
    33
  • FPN网络详解

    FPN网络详解特征图金字塔网络FPN(FeaturePyramidNetworks)是2017年提出的一种网络,FPN主要解决的是物体检测中的多尺度问题,通过简单的网络连接改变,在基本不增加原有模型计算量的情况下,大幅度提升了小物体检测的性能。低层的特征语义信息比较少,但是目标位置准确;高层的特征语义信息比较丰富,但是目标位置比较粗略。另外虽然也有些算法采用多尺度特征融合的方式,但是一般是采用融合后的特…

    2022年6月12日
    213
  • python : 建立属于自己的爬虫代理ip池

    python : 建立属于自己的爬虫代理ip池

    2021年11月10日
    48
  • 冻肉进口报关流程_企业如何取得报关资质

    冻肉进口报关流程_企业如何取得报关资质接单实操接到一票单子首先要审查进口企业是否有进口此产品的资质其次要审核单据是否单证相符单单相符单货相符最后整理资料。一、进口企业需要具备哪些资质及进口这类产品都有哪些条件?进口收货人需具备的资质:1.经营食品资质或食品流通许可证;2.进出口权;3.自动进口许可证;备注:没有以上资质或者资质不全,可以用代理资质双抬头报关;个人进口全用代理资质。关于肉类食品进口条件,海关条件:A.入境货物通关单;B.出境货物通关单;P:进境动植物、动植物产品检疫;Q:出境动植物、动植物产

    2022年9月16日
    2
  • hibernate id 生成器「建议收藏」

    hibernate id 生成器「建议收藏」hibernateid生成器1、identity:用于MySql数据库。特点:递增 ..    .注:对于MySql数据库使用递增序列时需要在建表时对主键指定为auto_increment属性。 2、sequence:用于Oracle数据库 ..   .     序列名.   .3、native:跨数据库时使用,由底层方言产生

    2022年6月21日
    29
  • bootstrap与vue区别_layui框架和vue哪个好

    bootstrap与vue区别_layui框架和vue哪个好layui,bootstrap和vue的区别

    2022年8月1日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号