官方文件連結:Selecting Contents for Uber JAR
由於 Apache 官網在國內訪問緩慢,筆者將這些實用資源整理保存於部落格,方便日後查閱。
Apache Maven Shade Plugin 是一個 Maven 打包插件,其核心功能是將專案構件及其依賴打包成一個「超級 JAR」(uber-jar),並支援對依賴類進行「著色」(shade),即重新定位套件名稱以避免類衝突。
透過 <artifactSet> 下的 <excludes> 可排除不想打入 Uber JAR 的依賴。以下配置排除了 classworlds、junit、jmock、xml-apis、Maven 內部測試類以及特定版本的 log4j:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
<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>
</execution>
</executions>
</plugin>
<filters> 允許針對特定 artifact 進行更細粒度的包含/排除規則。第一個 filter 僅保留 JUnit 的核心框架類,排除實驗性與 runner 相關類;第二個 filter 對所有 artifact 排除簽名相關檔案(*.SF, *.DSA, *.RSA),避免簽名衝突導致安全例外:
<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>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
設定 <minimizeJar>true</minimizeJar> 後,插件會分析專案程式碼實際引用的類,自動剔除未被引用的依賴類,進一步縮減 JAR 體積:
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
即使啟用了 minimizeJar,仍可透過 filters 強制完整保留 log4j 與 commons-logging 的所有類,防止因動態載入導致類丟失:
<filters>
<filter>
<artifact>log4j:log4j</artifact>
<includes><include>**</include></includes>
</filter>
<filter>
<artifact>commons-logging:commons-logging</artifact>
<includes><include>**</include></includes>
</filter>
</filters>
ShadeMojo.java,透過對應配置屬性與 Mojo 字段,可深入掌握其運作原理。掌握 includes/excludes 與 filters 的組合運用,能靈活控制 Uber JAR 內容,解決依賴衝突與體積膨脹問題。