網上有一些maven-shade-plugin替代maven-assembly-plugin的文章,緣由是代maven-assembly-plugin打出的jar包中要麼是不能設置Main-Class,要麼spring的META-INF/spring.*文件相互覆蓋了。對於這兩個問題,maven-assembly-plugin在當前的版本(3.1.0)中均可以解決了(方法見http://www.javashuo.com/article/p-qfvnhgwa-x.html)。html
實際上這兩個插件所針對的用途實際上是有差別的,而它們與maven默認的maven-jar-plugin都是打包插件,簡單的區別以下:spring
plugin | function |
---|---|
maven-jar-plugin | maven 默認打包插件,用來建立 project jar |
maven-shade-plugin | 用來打可執行包,包含依賴,以及對依賴進行取捨過濾 |
maven-assembly-plugin | 支持定製化打包方式,更可能是對項目目錄的從新組裝 |
當你只想將項目打成一個可執行包時,maven-shade-plugin很是適合。通常狀況下,pom文件中shade插件配置以下。apache
<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配置。api
Filter操做在打包時將jar包中的內容排除。它是以groupId:artifactId爲標識,在filter內部可使用<include>/<exclude>更細緻地控制,既能夠移除代碼文件,也能夠移除配置文件。maven
<!-- 按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>將項目中沒有使用的依賴自動移除ui
<configuration> <minimizeJar>true</minimizeJar> </configuration>
<minimizeJar>能夠和<filters>共同使用.net
<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。插件
ManifestResourceTransformercode
往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插件會覆蓋基於項目的jar包,而生成包含全部依賴的jar包。但有時須要原始的jar包和shade後的jar包同時被部署,能夠配置以下。
<configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <!-- 名稱會做爲後綴在shade構件jar包後 --> <shadedClassifierName>jackofall</shadedClassifierName> </configuration>
參考: