如何打一個FatJar(uber-jar)


如何打一個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>
  1. 首先使用maven-dependency-plugin把依賴全部copy到outputDirectory中,為了將包打到一個jar中,需要把outputDirectory配置到classes/lib中
  2. 使用maven-jar-plugin指定MainClass和classpath,需要注意的是classpathPrefix必須是${project.build.finalName}/lib路徑
  3. 執行命令
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

  1. AppendingTransformer 增加一個文件到resource
  2. XmlAppendingTransformer 增加一個xml到resource
  3. 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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM