EMT4J——讓 Java 應用升級更輕鬆

阿里云云棲號 發佈 2022-08-04T19:59:45.653623+00:00

前言JDK 升級對於 Java 應用來說是不得不面對的事情,一方面 Java 生態系統希望 Java 應用能跟上最新 JDK 版本:Oracle 建議將 JDK 的 LTS 版本的發布周期從 3 年調整為 2 年,對於只使用 LTS 版本的應用來說,可以在更短時間內使用最新的技術

前言

JDK 升級對於 Java 應用來說是不得不面對的事情,一方面 Java 生態系統希望 Java 應用能跟上最新 JDK 版本:

  • Oracle 建議將 JDK 的 LTS 版本的發布周期從 3 年調整為 2 年,對於只使用 LTS 版本的應用來說,可以在更短時間內使用最新的技術,但這也意味著版本升級會更加頻繁。
  • Spring Framework 6 只支持 JDK 17。Spring 是大多數企業級應用依賴的基礎框架,意味著不得不升級到 JDK 17。

但是另一方面,現實中的 Java 應用的 JDK 升級較為緩慢。JDK 11 從 2018 年發布近 4 年,已升級 JDK 11 仍未達到半數(2022-state-of-java-ecosystem)。而相比之下,JDK 8 發布之後 1 年內可達到 38%,兩年達到 64.3%,到 2018 年時近 80%(java-8-adoption-march-2016、JVM-ecosystem-report-2018)。

那為什麼升級 JDK 11 積極性不高呢?

可能的原因是多方面的。例如 JDK 8 在語言層面引入了 Lambda 對開發人員非常有吸引力,而 JDK 11 在語言層面的更新顯得可有可無。但是有一點是非常明顯的,相比從其它版本升級到 JDK 8(JDK 6/7 升級到 JDK 8 對於應用基本無感),升級到 JDK 11/17 難度會大很多,可能會遇到很多兼容性問題,如:

1、刪除了一些 API 如 sun.misc.*導致代碼出現 ClassNotFoundException。

2、Java Version 的 Schema 發生變化導致原來判斷 Java 版本的邏輯出現異常。

3、用戶代碼中使用了私有的 API,使用了標記為廢棄的 API 等。

4、JPMS(Java Platform Module System)的引入導致一些反射代碼會無法工作。

5、刪除了 J2EE 相關的包。

如果需要升級的應用依賴了成百上千的二方和三方 jar,而這些 jar 可能也存在兼容性問題,更進一步,如果需要升級的應用幾十個甚至幾百個,那麼帶來的額外工作量可想而知。

正是由於上述的困難,阿里巴巴內部將這些升級的經驗通過工具沉澱下來,希望能夠通過工具幫忙更多的 Java 應用更高效的升級最新版本 JDK。

EMT4J 簡介

目前 Eclipse Migration Toolkit for Java(簡稱「EMT4J」)已經在 Eclipse 社區開源,並通過了 Eclipse Adoptium PMC 評審,作為 Eclipse Adoptium 子項目進行孵化。阿里雲也是 Eclipse Adoptium 工作組的戰略基石成員,參與 Eclipse Adoptium 社區治理,為 Java Ecosystem 提供完全兼容的、基於 OpenJDK 的高質量 JDK 發行版。

EMT4J 目前支持了從 JDK 8 升級到 JDK 11&17 的分析,後續也會不斷的更新對於最新的 LTS 版本的支持。

目前支持通過如下 3 種方式使用:

  • Java Agent
  • 命令行工具
  • Maven插件

EMT4J 架構圖如下:

EMT4J——工具使用(場景演示)

以一個常見的場景來說明工具的使用:

開發人員張三接到任務,需要將所在團隊負責的 8 個 Java 應用(app-service-1 到app-service-8)從 JDK 8 升級到 JDK 17,那張三在 EMT4J 的幫助下如何升級呢?

具體升級操作我們分以下七步走:

1、張三下載了 EMT4J 工具到本地,並且在 /home/jdk17 本地安裝了目標版本的 JDK 17。

2、將 app-service-1~app-service-8 的應用包下載到 EMT4J 所在機器,放在目錄 /home/app/deploy,並將 app-service-1~app-service-8 的 JVM 選項放入到 .cfg 的文本文件,放在目錄 /home/app/vmoptions。

3、運行工具檢查:sh ${EMT4J_HOME}/bin/analysis.sh -f 8 -t 17 -j /home/jdk17 /home/app,其中 -f 8 -t 17 表示從 8 升級到 17, -j /home/jdk17 表示目標版本 JDK 的安裝目錄,/home/app 表示需要檢查的應用包以及參數文件。命令執行完成以後,默認會在當前目錄生成 report.HTML。打開檢查報告report.html 查看到問題的列表如下:

4、張三點擊"The schema of java version changed in JDK9"查看問題的詳情,看到提示如下具體的類:Location: file:/home/app/deploy/app-service-1/notify-utils-2.2.5.jar, Target: com.app.services1.utils.VersionInfo

5、張三打開 app-service-1 的工程看到如下的代碼,下面的代碼顯然是無法處理類似於 17.0.1 版本號。

private final String JAVA_VERSION = System.getProperty("java.version");   
private final int getJavaVersionAsInt() {
    if (this.JAVA_VERSION == null)
        return 0; 
    String str = this.JAVA_VERSION.substring(0, 1);
    str = str + this.JAVA_VERSION.substring(2, 3);
    if (this.JAVA_VERSION.length() >= 5) {
        str = str + this.JAVA_VERSION.substring(4, 5);
    } else {
        str = str + "0";
    } 
    return Integer.parseInt(str);
}

6、張三參考報告中的 How to fix 了解到 JDK 9 以後 Java Version 的 Schema 發生了變化,按新的 Schema 修改代碼。

7、張三按依次參考報告中對其它問題修改。修改完成以後,在開發機器上使用目標版本 JDK 啟動驗證功能正確性。

EMT4J——工具特性一覽

以上使用 EMT4J 工具幫助張三從 JDK 8 成功地升級到 JDK 17,那麼 EMT4J 工具具有哪些特性?

1、支持 Java Agent、命令行工具以及 Maven 插件等方式使用

  • Java Agent 可以獲取更多運行時上下文信息,能提供準確調用棧,能發現更多的問題
  • 命令行工具方便使用,無須啟動應用,但是可能會存在誤報
  • Maven 插件可以集成在構建階段,可在開發階段發現問題

2、支持多種潛在不兼容性問題分析

  • JDK 8 到 JDK 11
    • JDK Internal API 的使用
    • System ClassLoader 不再是 URLClassLoader 子類
    • Arrays.asList 返回類型變化
    • Java Version 的 Shema 發生變更
    • JPMS 需要增加 add-exports 和 add-opens
    • 時區數據變更為 CLDR 引起相關不兼容
    • Pattern.compile 的 API 變更
    • JVM 選項變更
    • ...
  • JDK 11 到 JDK 17
    • 刪除了 Nashorn
    • 刪除了RMI 和 Java Applet
    • 部分 Class 無法反射獲取 Field
    • ...

3、支持 HTML、TXT 和 JSON 格式的輸出

如何參與貢獻?

如果您在使用 EMT4J 的過程中,遇到如下的問題:

  • 工具應該發現的兼容性問題,但是實際沒有發現
  • 工具報告的問題上下文不準確,不方便查找問題在哪裡
  • 工具報告的問題描述不清晰,難以指導如何修改增加一些新的功能,比如工具支持其它一些格式
  • ...

都可以通過如下的方式參與貢獻:

  • 創建 issue 描述您遇到的問題
  • 自己 Fork 以後修改測試後,並通過 PR 合入 master

結語:因為目前還有很多的 Java 應用仍然停留在 JDK 8上,所以這些應用正在規劃或者正在升級 JDK 中,希望通過 EMT4J 讓我們的升級工作更輕鬆一些。

我們在工具中沉澱了阿里巴巴升級 JDK 的經驗,但是肯定還有很多我們沒有遇到的兼容性問題,另外 JDK 新的版本不斷會發布,也會不斷有新的兼容性問題出來。我們希望通過開源的方式,能夠有更多的開發者參與到工具中,給工具不斷增強功能,讓更多的 Java 應用升級變得更簡單。更多內容 (如何使用、貢獻等) 可以參考:https://github.com/adoptium/emt4j

原文連結:https://click.aliyun.com/m/1000351846/

本文為阿里雲原創內容,未經允許不得轉載。

關鍵字: