iT邦幫忙

2025 iThome 鐵人賽

DAY 10
0
Software Development

我們與Maven的距離系列 第 21

Day20 - JAR Packaging:Uber / Fat JAR

  • 分享至 

  • xImage
  •  

前言

昨日介紹了Executable JAR,我們若有使用第三方套件則需加入classpath資訊到Mainfest中,如果真實相依的JAR路徑一換就會無法執行,所以也就出現了我們今天要介紹的主題

何謂Uber / Fat JAR?

Uber JAR又稱為Fat JAR,胖胖的JAR(笑),Über在德文中有「超越」的意思(實際上與英文的 over 同源),可以理解為超越JAR的超級JAR。顧名思義就是把運行要用的都塞在一個JAR裡面了,不用擔心Maifest檔中的lib路徑是否設對,不用再擔心lib在資料夾班刪除或是java -cp路徑是否完整。

優缺點比較

下表從多個維度評估 Fat / Uber JAR,協助判斷是否採用:

維度 優點 缺點
部署 / 發佈 單一檔案即可發佈與部署 檔案體積常 30–100MB+,頻繁發佈耗頻寬時間
依賴整合 直接 + 傳遞依賴全數內嵌,避免漏帶 版本衝突較隱性,難定位來源
執行方式 java -jar 即可;無需維護複雜 classpath 若需替換單一依賴需整包重建
SPI / ServiceLoader 所有 provider 都被打進同一檔 META-INF/services 可能被覆蓋只剩最後一份
META-INF 資源 基本資源集中,部署直覺 spring.factories / spring.schemas / 簽章檔可能被覆蓋或破壞
可維護性 發佈流程簡化 不利細粒度更新;debug 時 class 來源混淆
適用場景 CLI 工具、快速 Demo、單體微服務 大型長期維運系統、需頻繁換依賴 / 配置

範例演示 - maven-shade-plugin

pom.xml設定如下,詳官網設定說明

<plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.5.1</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>com.mycompany.App</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>

將第三方JAR的class資料夾合在一起
https://ithelp.ithome.com.tw/upload/images/20251005/20128084TY9yumVag4.png
第三方JAR的資訊也合併在其中
https://ithelp.ithome.com.tw/upload/images/20251005/20128084GPwe8ov3z4.png

小結

Uber-JAR有其便利性,但專案一大檔案的大小就會在傳輸上顯露缺點,plugin合併第三方JAR的內容可能會涉及License問題,需視專案複雜度審慎使用

Reference


上一篇
Day19 - JAR Packaging Discussion
下一篇
Day21 - JAR Packaging:Distribution ZIP
系列文
我們與Maven的距離24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言