原文はこちら。
This article was written by Nicolai Parlog (Java Developer Advocate at Oracle).
https://inside.java/2024/12/09/quality-heads-up/
OpenJDK Quality Groupは、リリースの全体的な品質向上の手段としてOpenJDKビルドを使ってのFOSSプロジェクトのテストを推進しています。
Quality Outreach
https://wiki.openjdk.java.net/display/quality/Quality+Outreach
このHeads upは、関係するプロジェクトに送られる定期的なコミュニケーションの一部です。このプログラムの詳細と参加方法については、上記wikiをご覧ください。
Native Access and Integrity by Default
Javaコードとネイティブコード間のやりとりは、それがJNI (Java Native Interface) 経由であれ、FFM (Foreign Function & Memory) API経由であれ、JVMのクラッシュを引き起こすなど、アプリケーションやJavaプラットフォーム自体のintegrity(信頼性)を損なう可能性がある点で危険です。これは、ネイティブコードの実行完了後であったとしてもです。integrity by defaultのポリシーによれば、integrityを損なう可能性のあるすべてのJDKの機能は、アプリケーション開発者から明示的な承認を得る必要があります。
JEP draft: Integrity by Default
https://openjdk.org/jeps/8305968
その準備として、JEP 472により、JDK 24ではJNIとFFMの動作が以下のようになります。
JEP 472: Prepare to Restrict the Use of JNI
https://openjdk.org/jeps/472
- すべての制限付き操作について警告を表示する(将来的なリリースで例外に変更することを目標とする)
- コマンドラインオプション
--enable-native-accessおよび--illegal-native-accessを拡張し、両APIの制限付き操作を管理する。
注意いただきたいのは、これはJNIの使用を妨げたり、廃止したり、あるいは削除したりする意図はありませんし、JNIまたはFFM経由で呼び出されるネイティブコードの動作を制限する意図もない、ということです。目的は、アプリケーションの運用者が必要に応じて選択的にオプトアウトできるツールを提供しながら、アプリケーションとJavaプラットフォームのintegrity by default(デフォルトの信頼性)を確保することです。
Restricted Operations
以下のJNIの操作は制限付き(restricted)と見なされます。
System::loadLibrary、System::load、Runtime::loadLibrary、Runtime::loadの呼び出し- ネイティブメソッドの宣言
以下のFFMの操作は制限付き(restricted)と見なされます。
AddressLayout::withTargetLayoutLinker::downcallHandleLinker::upcallStubMemorySegment::reinterpretModuleLayer.Controller::enableNativeAccessSymbolLookup::libraryLookup
ドキュメントには、すべての制限付きメソッドの一覧が含まれています。このリストは常に最新を保つようにしています。
Restricted Method List (Java SE 24 & JDK 24 [build 28])
https://download.java.net/java/early_access/jdk24/docs/api/restricted-list.html
Enabling/Disabling Restricted Operations
制限付き操作を実行した場合、デフォルトで標準エラー出力に以下のような出力が出ます。
WARNING: A restricted method in java.lang.System has been called
WARNING: System::load has been called by com.foo.Server in module com.foo (file:/path/to/com.foo.jar)
WARNING: Use --enable-native-access=com.foo to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
これはJNIに対する変更であり、これまでこのような警告の表示はありませんでしたし、FFMについても同様で、これまでは制限付きの操作はデフォルトで禁止されていました点にご注意ください。JDK 24から、両APIは警告を表示するという点で統一されていますが、将来的には両方とも例外をスローするようになります。この動作は、2つのコマンドラインオプション --enable-native-access および --illegal-native-access で設定できます。
--enable-native-access=$value というオプションは、
$valueがALL-UNNAMEDの場合はクラスパス全体、もしくは$valueがcom.mod1,com.mod2のような場合はリスト化したモジュール
に対して、すべての制限付き操作を有効化します。これは制限付きのネイティブ操作に対するアクセスを可能にするための、長期的にサポートされる方法です。
そのオプションでネイティブアクセスが有効になっていない場合、コードが制限付きの操作を実行することはできません(illegal)。新しいオプション --illegal-native-access=$value を使って、$valueに応じて、Javaランタイムがそのようなケースをどのように処理するかを決定します。
allow: 操作を許可warn: 上記のような警告を発行(これがJDK 24のデフォルト)deny:IllegalCallerExceptionをスロー
今後のリリースでは、denyがデフォルトになって、allowが除去される予定です。JDK 9で導入された --illegal-access のように、このオプションをデフォルト値より低い値(例えばJDK 24だとallow)に設定するのは、 --enable-native-access の正しい利用方法が確立するまでの短期的な修正策と見なしておくべきでしょう。また--illegal-accessのように、--illegal-native-accessを使い、将来のより幻覚なJavaリリースに向けてプロジェクトの準備をすることもできます。
JDK 24でJNIまたはFFMを使用するアプリケーションを実行する推奨方法は以下の通りです。
java --enable-native-access=$value --illegal-native-access=deny ...
ここで、$valueは理想的には制限付きの操作にアクセスするモジュールの名前のリストです。そうでない場合、このようなコードがクラスパス上に存在する場合はALL-UNNAMEDとなります。
More
JNI を使用するライブラリを特定するのに役立つものとして、新しいJDKツール(仮称jnativescan)が導入されます。これは指定されたモジュールパスやクラスパス中のコード静的スキャンし、制限付きメソッドの利用とネイティブメソッドの宣言をレポートするものです。
The jnativescan Command
https://download.java.net/java/early_access/jdk24/docs/specs/man/jnativescan.html
ネイティブライブラリのロード(アンロード)を追跡したい場合は、JDK フライトレコーダーのイベント jdk.NativeLibraryLoad および jdk.NativeLibraryUnload を確認してください。
JEP 472: Prepare to Restrict the Use of JNI
https://openjdk.org/jeps/472
[JDK-8324665] Loose matching of space separators in the lenient date/time parsing mode
https://bugs.openjdk.org/browse/JDK-8324665