idea使用maven打jar包踩坑记录+maven打jar包插件比较
jar包分为普通jar包和可依赖jar包。当我们使用maven把项目打成一个jar包时,默认情况下,只会把当前项目的代码编译文件打入jar包中,而这个项目所依赖的第三方jar包,并不会自动加入到新打的jar包中。这样会造成使用jar包时,报错ClassNotFoundExcepiton,需要使用maven的Assembly插件设置jar包的打包方式。
综述
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包一般有如下几个插件:
- maven-jar-plugin;
- maven-assembly-plugin;
- 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打成压缩文件,以后只需要传送更改的代即可。
更多推荐



所有评论(0)