背景
直接用 mvn package打包了,结果是报错,没有主清单属性,然后百度了一堆,发现都是用maven-shade-plugin
这个插件,还有用maven-assembly-plugin
,以及maven-jar-plugin
。由于看着 maven-jar-plugin
插件的代码配置最短,我就用了。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
定义主类的入口地址就是TestMain的全路径
<mainClass>com.spider.culture.main.Starter</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
结果也报错,NoclassDefFoundError org.apache.logging.log.LogManager
。
显然是没把jar打包进去,折腾半天我就换了个配置。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.spider.culture.main.Starter</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
用这个打包就可以了。
分析
问题:那么这三个插件参加分别有什么呢?
参考来源:http://www.infoq.com/cn/news/2011/06/xxb-maven-9-package
maven-jar-plugin
Maven打包jar用的默认插件是maven-jar-plugin
,默认Maven生成的JAR包只包含了编译生成的.class文件和项目资源文件。
通过maven-jar-plugin
插件打包的jar的目录结构(与以下插件生成的目录结构对比):
要得到一个可以直接在命令行通过java
命令运行的jar文件,还要满足两个条件:
- jar包中的
/META_INF/MANIFEST.MF
元数据文件必须包含Main-Class
信息; - 项目所有的依赖都必须在
Classpath
中。
而maven-shade-plugin
就可以实现这个功能。
maven-shade-maven
它可以让用户配置Main-class的值,然后在打包的时候将值填入/META-INF/MANIFEST.MF
文件。关于项目的依赖,它聪明地将依赖jar
文件全部解压后,再将得到的.class
文件连同当前项目的.class
文件一起合并到最终的CLI(Command Line)
包中。
通过maven-shade-plugin
插件打包的jar的目录结构:
所以我们可以直接使用java -jar
命令运行程序。
maven-assembly-plugin
最强大的Maven打包插件。它支持各种打包格式,包括zip、tar.gz、tar.bz2等等,通过一个打包描述文件(assembly.xml),能够帮助用户选择具体的打包哪些文件集合、依赖、模块、和本地仓库文件,每个项的具体打包路径用户也能自由控制。
使用场景
通过以上描述,相信大家已经能明白各插件的使用场景。
maven-jar-plugin
用于第三方库。如果我们写的项目是用于为别人提供使用的时候,我们可以不需要打包依赖包。可以打开maven本地仓库看看各jar的打包格式,就是这种的。
maven-shade-plugin
用于需要运行的jar,如果是有主类,想直接在JRE上运行的程序,可以使用这种插件打包,它会把依赖库都打包进jar中。
maven-assembly-plugin
如果有更复杂的打包需求,不仅需要项目的字节码,还得包含依赖以及相关脚本文件一方便客户解压后就能运行。这时候就可以使用此插件自定义包的格式。