Maven学习(六) - 插件maven-shade-plugin

网上有一些maven-shade-plugin替代maven-assembly-plugin的文章,原因是代maven-assembly-plugin打出的jar包中要么是不能设置Main-Class,要么spring的META-INF/spring.*文件相互覆盖了。对于这两个问题,maven-assembly-plugin在当前的版本(3.1.0)中都可以解决了(方法见https://my.oschina.net/u/2377110/blog/1584205)。

实际上这两个插件所针对的用途其实是有差异的,而它们与maven默认的maven-jar-plugin都是打包插件,简单的区别如下:

|plugin|function| | -- | -- | |maven-jar-plugin|maven 默认打包插件,用来创建 project jar| |maven-shade-plugin|用来打可执行包,包含依赖,以及对依赖进行取舍过滤| |maven-assembly-plugin|支持定制化打包方式,更多是对项目目录的重新组装|

当你只想将项目打成一个可执行包时,maven-shade-plugin非常适合。一般情况下,pom文件中shade插件配置如下。

<build>       <plugins>           <plugin>               <groupId>org.apache.maven.plugins</groupId>               <artifactId>maven-shade-plugin</artifactId>               <version>1.4</version>               <executions>                   <execution>                       <phase>package</phase>                       <goals>                           <goal>shade</goal>                       </goals>                       <configuration>                           <filters>                               <filter>                                   <artifact>*:*</artifact>                                   <excludes>                                       <exclude>META-INF/*.SF</exclude>                                       <exclude>META-INF/*.DSA</exclude>                                       <exclude>META-INF/*.RSA</exclude>                                   </excludes>                               </filter>                           </filters>                           <transformers>                               <transformer                                   implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">                                   <mainClass>com.lcifn.Application</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>                   </execution>               </executions>           </plugin>       </plugins>   </build>   

shade插件绑定的是package生命周期目标,并设置com.lcifn.Application为Main-Class,以及将META-INF/spring.*文件合并(追加而非覆盖),并过滤掉所有依赖的META/INF中SF,DSA,RSA后缀文件。这里涉及到filter配置和transformer配置。

filters和artifactSet

Filter操作在打包时将jar包中的内容排除。它是以groupId:artifactId为标识,在filter内部可以使用<include>/<exclude>更细致地控制,既可以移除代码文件,也可以移除配置文件。

<!-- 按package过滤junit包 --> <configuration>     <filters>         <filter>         	<artifact>junit:junit</artifact>         	<includes>         		<include>junit/framework/**</include>         		<include>org/junit/**</include>         	</includes>         	<excludes>         		<exclude>org/junit/experimental/**</exclude>         		<exclude>org/junit/runners/**</exclude>         	</excludes>         </filter>     </filters> </configuration> 

如果想将整个jar包都过滤掉,可以使用<artifactSet>,也是指定groupId:artifactId的标识。

<configuration> 	<artifactSet> 		<excludes> 			<exclude>classworlds:classworlds</exclude> 			<exclude>junit:junit</exclude> 			<exclude>jmock:*</exclude> 			<exclude>*:xml-apis</exclude> 			<exclude>org.apache.maven:lib:tests</exclude> 			<exclude>log4j:log4j:jar:</exclude> 		</excludes> 	</artifactSet> </configuration> 

另外配置<minimizeJar>将项目中没有使用的依赖自动移除

<configuration>     <minimizeJar>true</minimizeJar> </configuration> 

<minimizeJar>可以和<filters>共同使用

<configuration> 	<minimizeJar>true</minimizeJar> 	<filters> 		<filter> 			<artifact>log4j:log4j</artifact> 			<includes> 				<include>**</include> 			</includes> 		</filter> 		<filter> 			<artifact>commons-logging:commons-logging</artifact> 			<includes> 				<include>**</include> 			</includes> 		</filter> 	</filters> </configuration> 

资源转换

在打包时,存在将多个构件中的class文件或资源文件聚合的需求。shade插件提供了丰富的Transformer工具类。这里介绍一些常用的Transformer。

ManifestResourceTransformer

往MANIFEST文件中写入Main-Class是可执行包的必要条件。ManifestResourceTransformer可以轻松实现。

<configuration> 	<transformers> 		<transformer 			implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 			<mainClass>com.lcifn.Application</mainClass> 		</transformer> 	</transformers> </configuration> 

AppendingTransformer

用来处理多个jar包中存在重名的配置文件的合并,尤其是spring。

<configuration> 	<transformers> 		<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> 

ServicesResourceTransformer

JDK的服务发现机制是基于META-INF/services/目录的,如果同一接口存在多个实现需要合并 ,则可以使用此Transformer。

<configuration>   <transformers>     <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>   </transformers> </configuration> 

更多的Transformer见http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html

原始构件与shade构件

默认情况下,shade插件会覆盖基于项目的jar包,而生成包含所有依赖的jar包。但有时需要原始的jar包和shade后的jar包同时被部署,可以配置如下。

<configuration>   <shadedArtifactAttached>true</shadedArtifactAttached>   <!-- 名称会作为后缀在shade构件jar包后 -->   <shadedClassifierName>jackofall</shadedClassifierName>  </configuration> 

参考:

  1. http://maven.apache.org/plugins/maven-shade-plugin/index.html
  2. http://www.jianshu.com/p/14bcb17b99e0
注:本文转载自https://my.oschina.net/u/2377110/blog/1585553,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除。


评论

赞助商