目录
前言
概念
准备
打包方式
idea自带的maven工具
小包打包第一种方式
小包打包第二种方式
小包总结
大包打包
maven-compiler-plugin
依赖配置
打包测试
效果
maven-jar-plugin 和 maven-dependency-plugin
maven-jar-plugin
maven-dependency-plugin
依赖配置
效果
maven-assembly-plugin
缺点
依赖配置
效果
两者的区别
maven-shade-plugin
依赖配置
效果
两种第三方插件打包方式的总结
现在都是使用idea中maven插件来打包项目,因此此文章将基于idea中的maven插件打包。
打包分为小包和大包两种概念:
小包:只打包我们写的代码,不打包代码依赖的其他jar包。
大包:打包项目本身的代码以及项目所依赖的其他jar包。
因此,如果我们的项目代码只需要被别的代码引用,也就是不需要启动类去运行,那么打包成小包即可,如果我们的项目需要独立的运行,需要启动类去运行,那么就需要打包成大包。
我们先创建一个maven项目,创建一个启动类,随便引入一个其他依赖。
启动类
pom文件
首先使用idea中自带的maven工具打包,idea的maven工具也能打大包和小包。
小包打包直接运行maven中的package即可。
可以看到target目录下生成了jar包
查看生成的jar包
可以看到只有我们项目的代码,引入的依赖并没有被一起打包
这里也就不测试能不能通过命令java -jar *.jar 去运行jar包了,因为这是小包,根据小包的作用,我们是并不需要去运行。这里我可以告诉你,并不能运行,因为我们打包的时候并没有去指定启动类的路径,也就是在META-INF目录下的MANIFEST.MF文件中指定启动类。
大包打包我们是需要指定启动类并且将其他依赖一起打包的。
配置打包信息
配置完后,我们可以看到引入的依赖也在被打包的范围,同时如果我们不想打包某个jar包进来,可以在此面板选择删除,这样就不会一同被打包了。
然后去编译打包
可以看到生成了out输出文件夹,并且引入的依赖也一同被打包到同个目录下了,但是还是没有合并成同一个jar,如果要运行的话,必须将依赖的jar放在同一个目录中才能正常运行。
我们来查看以下生成的jar包
我们发现,打包的jar貌似比小包更简洁 ,而且也只有我们本身的java代码,没有MANIFTEST文件,没有的话肯定是无法运行的,因为里面记录启动类的路径以及依赖jar包的存放路径。
很奇怪,我们的MANIFEST文件跑到这里了,并没有被一同打包。
可以看到MANIFEST中已经生成了jar的存放路径和启动类的路径
原来,我们的这种打包方式必须要和打包插件共同使用,后面会介绍几种打包插件。
这样的打包方式也有解决方法,就是将我们打包的jar解压,将MANIFEST文件放进去再压缩,最后将压缩好的jar包和引入的jar包放在同一个目录中即可运行。
从 上面的两种方式可以看出来,idea自带的打包方式,只能打包成小包,源码的部分只有项目本身的代码。这种 Jar 包就是所谓的 “小包”。
从前面来看,打包打包需要使用到第三方插件,以下来介绍一些第三方的打包插件。
maven-compiler-plugin是一个Maven插件,可以用来指定项目源码的 jdk 版本,编译后的 jdk 版本,以及编码格式。,单独的使用并不会打包成大包,还是会打成小包,因此一般用来与其他第三方的打包插件联合使用。
maven-compiler-plugin
3.8.1
1.8
UTF-8
可以看到只有源码被打包而已。
maven-jar-plugin
和 maven-dependency-plugin
这两个插件是一起使用的,首先是不推荐使用这种,此种打包方式有一个比较明显的缺点:打包后会在 target
目录下生成 lib
目录(存放依赖 Jar)和项目 Jar。也就是说由于依赖都存在于 lib
目录中,所以要想运行 Jar 包,必须将 Jar 包和 lib
目录放在同一个路径下。
maven-jar-plugin
首先说 maven-jar-plugin
插件,它的思想就是:指定启动类、指定依赖包相对于项目最终 Jar 包所在的路径、给 MANIFEST.MF
文件添加 Class-Path
属性(运行项目 Jar 包时会根据 Class-Path
属性来找到其他依赖 Jar 包的路径),因此这个插件就是个配置 MANIFEST.MF
文件的插件。
maven-dependency-plugin
这个插件才是打包项目的其他依赖,因此这个必须配合上面的插件使用,两者缺一不可。
community
org.apache.maven.plugins
maven-jar-plugin
true
lib/
com.ronz.community.CommunityApplication
org.apache.maven.plugins
maven-dependency-plugin
copy-dependencies
package
copy-dependencies
${project.build.directory}/lib
所以说想要运行项目,必须将lib和源码jar包放在同一个目录下才行,这样显然是不太方便的。
maven-assembly-plugin
使用 maven-assembly-plugin
插件打出来的包只有一个 Jar 包,这个 Jar 包中包含了项目代码以及依赖的代码。也就意味着此种方式打出来的 Jar 包可以直接通过 java -jar xxx.jar
的命令来运行。而且我们可以联合maven-compiler-plugin插件来使用。
maven-assembly-plugin 同名类覆盖时会出现问题。
test
maven-compiler-plugin
3.8.1
1.8
UTF-8
org.apache.maven.plugins
maven-assembly-plugin
com.cw.HelloStart
jar-with-dependencies
make-assembly
package
single
test-jar-with-dependencies.jar
test.jar
明显可以看到test-jar-with-dependencies.jar才是我们需要的。
maven-shade-plugin
根据 Maven 的官方文档介绍,maven-shade-plugin
是一个强大的打包插件。它同样可以将项目的依赖以及项目的源码打包成一个可执行 Jar 包。
test
maven-compiler-plugin
3.8.1
1.8
UTF-8
org.apache.maven.plugins
maven-shade-plugin
3.2.4
package
shade
com.cw.HelloStart
META-INF/spring.handlers
META-INF/spring.schemas
使用第二种方式的 assembly
打包出来的 Jar 包多多少少有些问题,但是使用第三种方式打包出来的 Jar 包一般都是可用的。所以在将项目打包为大包时,还是推荐使用第三种打包的方式。
如果是大数据项目中,我们日常使用比较多的是maven-assembly-plugin
插件,例如:大数据项目中往往有很多shell
脚本、SQL
脚本、.properties
及.xml
配置项等,采用assembly
插件可以让输出的结构清晰而标准化。