综述

jar包分为普通jar包和可依赖jar包。当我们使用maven把项目打成一个jar包时,默认情况下,只会把当前项目的代码编译文件打入jar包中,而这个项目所依赖的第三方jar包,并不会自动加入到新打的jar包中。这样会造成使用jar包时,报错ClassNotFoundExcepiton,需要使用maven的Assembly插件设置jar包的打包方式。
Assembly插件官网地址

Assembly插件使用

想要打成的jar包把依赖的所有jar包打进去,需要在pom中配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass></mainClass><!-- 可执行jar包main方法入口 -->
            </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> <!-- 指定在打包节点执行jar包合并操作 -->
            <goals>
                <goal>single</goal><!-- 只运行一次 -->
            </goals>
        </execution>
    </executions>
</plugin>

配置好后,重新打的jar包,会把所依赖的jar包中的class文件,合并到新打的jar包中。在新打的jar包中,不会看到其他的jar包,而是把其他jar包的class按包名分类,下面的class文件都展示在了新打的jar包中。
下图为不用Assembly插件打包的效果,jar包里只有项目中的class文件:
在这里插入图片描述
因为项目里以com开头,所以第一层级的包名是com,下面都是本项目中的class文件。

下图为使用Assembly插件,把依赖包也打进来的效果:
在这里插入图片描述
可以看到,第一层级的包名,除了com,还有好多其他的包。这些都是依赖的第三方jar包打成的class文件。

maven打包插件对比

我们在平时开发时,一般都是利用现成的框架进行开发,然后打包成服务运行。打包时会生成一个lib目录,里面是依赖的jar包。而上面的描述,并没有lib目录的存在。这是怎么回事儿呢?根本原因是使用maven打jar包的插件不同引起的。

maven打jar包一般有如下几个插件:

  1. maven-jar-plugin;
  2. maven-assembly-plugin;
  3. spring-boot-maven-plugin

下面比较一下这几个插件的区别与特点。

maven-jar-plugin

使用maven-jar-plugin插件, 默认的打包方式,即不生成依赖jar包。用来打普通的project JAR包 。

<build>
   <plugins>
       <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <!-- 可执行jar包需要指定入口函数 然后通过java -jar执行 -->
                        <mainClass>类的全路径名称</mainClass>
                        <!-- 是否添加依赖的jar路径配置 -->
                        <addClasspath>true</addClasspath>
                        <!-- 依赖的jar包存放位置,和生成的jar放在同一级目录下 -->
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
                <!-- 不打包com.artisan.excludes下面的所有类 -->
                <excludes>com/artisan/excludes/*</excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

maven-assembly-plugin

这就是上面提到的插件。在应用开发中你是否想要创建一个包含脚本、配置文件以及所有运行时所依赖的元素(jar)的发布jar包。Assembly插件能帮你构建一个完整的发布包。
该插件不仅支持创建二进制归档文件,也支持创建源码归档文件。这些assemblies定义在一个assembly描述符文件里。你可以选择自定义assembly描述符或者直接使用插件自带的三个预定义描述符中的任何一个.

目前Assembly插件支持如下格式的归档文件:

tar.gz
tar.bz2
jar
dir
war
and any other format that the ArchiveManager has been configured for

maven-assembly-plugin作用:用于将 Maven 项目打包成可执行的程序或分发包,将项目中的代码、资源和所有依赖包的内容打成一个程序集。

spring-boot-maven-plugin

专为 Spring Boot 项目设计,适合需要创建包含嵌入式服务器的可执行 JAR 文件的项目。
用spring boot快速开发时,通常用spring-boot-maven-plugin插件将springboot的应用程序打包成jar文件,然后通过java -jar运行,很方便。但是如果是部署到服务器上,每次更改代码后替换的包都比较大,至少30MB以上,依赖jar多的甚至超过100MB,传输效率就降低了,其实真正的代码jar是很小的,所以要想办法给jar瘦身。
spring-boot-maven-plugin主要目标是spring-boot的启动、停止、运行和repackage,对于打包来说那就是repackage,也就是说它实现的打包功能是重新打包,原始jar包还是由maven-jar-plugin生成的。

在这里插入图片描述
我们将普通插件maven-jar-plugin生成的包和spring-boot-maven-plugin生成的包进行比较,发现使用spring-boot-maven-plugin生成的jar中主要增加了两部分,第一部分是lib目录,这里存放的是应用的Maven依赖的jar包文件,第二部分是spring boot loader相关的类,所以通常spring-boot-maven-plugin插件打的jar包程为fatjar或者胖jar。
所以如果是用部署到生产或者服务器环境最好通过maven-jar-plugin打包,初次打包可以结合maven-assembly-plugin打成压缩文件,以后只需要传送更改的代即可。

Logo

一站式 AI 云服务平台

更多推荐