JDK 24 首項公開功能 JEP 472 為限制使用 JNI 做準備

JDK 24 with JEP 472 page

JDK 24 現況

JDK 23官方規格)即將於今年 9 月份發布,緊接著後續的 JDK 24官方規格) 開發工作也已如火如荼地展開,並預計於 2025 年 3 月發布。JDK 24 屬於非長期支援(LTS)的版本之一,這意味著它與 JDK 23 一樣,將只會獲得 Oracle 六個月的 Premier 支援。

可以預期的是,許多已包含在 JDK 23 中的預覽功能,都可望被納入 JDK 24 之中,例如像是:

除了上述所列的預覽功能之外,JDK 24 第一個出爐的新功能是 JEP 472 Prepare to Restrict the Use of JNI(限制 JNI 使用的準備)

JDK 24 首項功能:JEP 472 簡介

JEP 472 的任務是「限制 Java Native Interface 使用」的準備工作。當我們使用 JNI 時,JVM 就會發出警告。JDK 22 中引入的JEP 454 外部函式和記憶體 APIForeign Function & Memory API,作為 JNI 替代方案)也同樣包含在內,因此使用 FFM API 時也會發出警告。其目的是幫助我們為未來的 Java 版本做好準備,並透過統一限制 JNI 和 FFM API 的使用來確保預設情況下的完整性。我們在必要時可以透過選擇性地指定選項來避免產生警告(現在階段)和禁止執行的限制(未來階段)。

該功能的目標有:

  • 保留 JNI 作為與原生程式碼相互操作的標準方式
  • 預設不允許與原生程式碼互動,無論是使用 JNI 或 FFM API,除非我們在程式啟動時明確指定啟用 JNI 或 FFM API
  • 調整 JNI 和 FFM API 的使用,讓函式庫的維護人員能順利轉移而無需開發人員變更命令列選項
  • 它並非要棄用 JNI,也並非要從 Java 平台中移除 JNI,同時也沒有要限制 JNI 呼叫原生程式碼

JNI 的問題

JNI 是在 JDK 1.1 時引入的,目的是做為 Java 程式碼與原生程式碼之間互相操作的主要方式。它允許 Java 程式碼呼叫原生程式碼(下行呼叫、downcall),以及原生程式碼呼叫 Java 程式碼(上行呼叫、upcall)。不幸的是,它們之間的任何交互操作都是有風險的,很可能會損害應用程式和 Java 平台本身的完整性。根據「預設情況下的完整性」政策,所有能夠破壞完整性的 JDK 功能都必須獲得開發人員的允許。下面列出了四種交互操作的風險:

  1. 下行呼叫可能導致任意的未定義行為,包括 JVM 當機。這些問題無法在 Java 執行時期預防,也無法拋出異常讓 Java 程式碼有機會去捕獲並處理
  2. 原生程式碼和 Java 程式碼之間經常利用直接位元組緩衝區交換資料,而這些緩衝區是垃圾收集器無法觸及的記憶體區域,最終變成了未受控管的灰色地帶。原生程式碼可能會產生一個無效記憶體區域的位元組緩衝區,如果在 Java 程式碼中使用它的話會導致未定義的行為
  3. 原生程式碼可以用 JNI 繞過 JVM 的存取檢查,像是直接存取欄位與呼叫方法。另外,原生程式碼甚至可以利用 JNI 在 final 欄位初始化很久之後去更改它們的值。因此,呼叫原生程式碼具有破壞 Java 程式碼完整性的風險存在
  4. 原生程式碼如果不正確使用某些 JNI 函數,可能導致垃圾收集器出現不良行為,而這種行為可能在程式的任何生命週期階段中發生。例如,存取臨界區域(critical region)但卻未釋放它,導致垃圾收集區無法回收物件

在 JDK 22 引入的 FFM API 一樣具有上述前二項的風險。採取的應對策略是將可能破壞完整性和不會破壞完整性的操作分開,因此 FFM API 之中有部分被歸類為受到限制的方法。這代表在程式執行時,我們必須使用 java 命令列選項去解開它們的封印。JNI 也應該要效仿 FFM API,以實現預設情況下的完整性。

後續版本

下一個 LTS 版本 JDK 25 預計將於 2025 年 9 月發布。以目前的使用現況來看,LTS 版本在 Java 社群中的使用比例佔據了極高的主導地位。以 New Relic 在今年 4 月的報告(來源)來看,至少有 98% 以上的用戶採用 Java LTS 版本,包括 8、11、17 和 21。這意味著 JDK 23 和 JDK 24 的採用率應該會非常低,因為大部分的用戶會期望使用 LTS,也就是接下來的 JDK 25。

本篇文章的內容為老喬原創、二創或翻譯而來。雖已善盡校對、順稿與查核義務,但人非聖賢,多少仍會有疏漏之處難以避免。如果大家有任何問題、建議或指教,都歡迎在底下留言與老喬討論!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

one × one =

返回頂端