如何打一個FatJar(uber-jar)
FatJar也就叫做UberJar,是一種可執行的Jar包(Executable Jar)。FatJar和普通的jar不同在於它包含了依賴的jar包。
1. maven-jar-plugin
例子
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.yourcompay.Demo</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
- 首先使用maven-dependency-plugin把依賴全部copy到outputDirectory中,為了將包打到一個jar中,需要把outputDirectory配置到classes/lib中
- 使用maven-jar-plugin指定MainClass和classpath,需要注意的是classpathPrefix必須是${project.build.finalName}/lib路徑
- 執行命令
java -jar ./target/demo.jar
注意:采用maven-jar-plugin方式有個缺點,demo.jar不能移動到其他路徑下面執行java -jar命令,因為demo.jar依賴放在了lib/目錄下
解決方法有點復雜,首先用maven-dependency-plugin把依賴copy到${project.build.directory}/classes/lib,然后需要自定義jar加載的classloader,真復雜...
2. maven-assembly-plugin
maven-assembly-plugin是一個強大的打包工具,除了jar包還能打zip、tar.gz、tar.bz2等類型的包,描述文件放在assembly.xml中
如何用assembly打一個FatJar,使用預定義格式jar-with-dependencies打包
實際上
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.yourcompany.Demo</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
執行命令make clean package,得到demo-jar-with-dependencies.jar,這時我們就可以使用java -jar命令了
注意:預定義格式jar-with-dependencies實際上只有基本的FatJar打包功能,背后集成是maven-shade-plugin。下一節就講shade-plugin
3. maven-shade-plugin
3.1 一個簡單的例子
maven-shade-plugin將goal shade:shade綁定到maven的package階段
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
執行命令maven package在target目錄下生成一個demo.jar
3.2 設置MainClass創建一個可執行的Jar包
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.yourcompany.Demo</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
執行mvn package命令生成一個demo.jar,執行demo.jar
java -jar ./target/demo.jar
3.2.1 Resource Transformers
- AppendingTransformer 增加一個文件到resource
- XmlAppendingTransformer 增加一個xml到resource
- ManifestResourceTransformer 設置MANIFEST
3.3 使用include/exclude指定需要打包的jar
在configuration元素下增加includes和excludes節點
<configuration>
<artifactSet>
<includes>
<include>org.apache.commons:commons-langs</include>
</includes>
<excludes>
<exclude>com.alibaba:fastjson</exclude>
</excludes>
</artifactSet>
</configuration>
3.4 使用filter過濾jar包中的類或者資源
在configuration元素下增加filters節點
<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>
3.5 maven-shade-plugin 自動將所有不使用的類全部排除掉
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>