Head toward Java 17 and Java 18 #jjug_ccc

スライド概要

This slide is for Java Japan User Group CCC 2021 Fall.

profile-image

KUBOTA Yuji

@ykubota

作者について:

performance, site reliability engineering mania

スライド一覧
シェア
埋め込む»CMSなどでJSが使えない場合

公開日

2021-11-21 14:00:00

各ページのテキスト

1. Head toward Java 17 and Java 18 KUBOTA Yuji LINE Corporation JJUG CCC 2021 Fall

2. KUBOTA Yuji (@sugarlife) Software Engineer of internal Kafka platform at LINE Corp. OpenJDK Author / IcedTea committer https://www.slideshare.net/YujiKubota/

3. Java 17 Release 2021/9/14 https://mail.openjdk.java.net/pipermail/jdk-dev/2021-September/006037.html Long Term Support Java 11以来3年ぶり

4. LTS: Long Term Support 長期サポートバージョン OpenJDKコミュニティの各バージョンの開発サイクルは半年ごと ディストリビュータによって期間は異なる よくある誤解 OpenJDKコミュニティのLTS -> OpenJDKコミュニティはバイナリを配布していな い LTSは全機能が標準機能 -> 試験的機能も盛り込まれる LTSじゃないと性能は悪い -> LTSかどうかに関係なく全バージョンに対して商用に 耐えうる安定性が求められている (OpenJDK ML)

5. LTS対象バージョン変更の提案 3年毎から2年毎への変更提案。これに則ると次のLTSはJava 21 Oracleはそうする予定 https://mreinhold.org/blog/forward-even-faster https://www.oracle.com/news/announcement/oracle-releases-java-17-2021-09-14/

6. Resources (1/2) Source code: https://github.com/openjdk/jdk JDK17 Updates: https://github.com/openjdk/jdk17u JEP (JDK Enhancement-Proposal) Java新機能拡張の提案 14 JEPs for Java 17 4 JEPs for Java 18 CSR (Compatibility & Specification Reviews) 非互換性を伴う変更のレビュー(非互換性を伴う変更は出す必要がある) 192 CSRs for Java 17 78 CSRs for Java 18

7. Resources (2/2) Release note 各製品ごとの変更点。OpenJDKやOracle JDKで書かれている内容がすべての製品にあてはま るわけではないのことに注意 OpenJDK: JBS Oracle JDK: https://www.oracle.com/java/technologies/javase/jdk-relnotes-index.html New API since JDK 11: https://docs.oracle.com/en/java/javase/17/docs/api/new-list.html (恐らくLTSなので特例) JEPs since JDK 11: https://openjdk.java.net/projects/jdk/17/jeps-since-jdk-11 Un-official auto-generated sites Release note: https://builds.shipilev.net/backports-monitor/release-notes-17.html VM Options Explorer: https://chriswhocodes.com/vm-options-explorer.html

8. Glossary Incubator (JEP 11) Java APIの試験用モジュール( jdk.incubator )。標準化に向けてフィードバックを得て変更 しやすいように特別なモジュールにしている。有効にするには --add-modules jdk.incubator.xxx の指定が必要 Preview (JEP 12) Java言語の試験機能。有効にするには --enable-preview の指定が必要。コンパイル時に は --resource か -source の指定も必要 Experimental GCやコンパイラなどのランタイムの試験機能。 -XX:+UnlockExperimentalVMOptions オ プションをあわせて指定して実行する Standard 上記のテストフェーズを通じて標準機能に昇格した機能。通例2回以上のバージョンアップを 挟んで昇格する(例:Preview -> Second Preview -> Standard)

9. Java 17 14 Java Enhancement-Proposals Project page: https://openjdk.java.net/projects/jdk/17/ JBS 192 Compatibility & Specification Reviews JBS

10. Additions JEP 403: Strongly Encapsulate JDK Internals HosSpot JVM JEP 391: macOS/AArch64 Port Libraries JEP 382: New macOS Rendering Pipeline JEP 356: Enhanced Pseudo-Random Number Generators JEP 415: Context-Specific Deserialization Filters JEP 412: Foreign Function & Memory API (Incubator) JEP 414: Vector API (Second Incubator) Language JEP 306: Restore Always-Strict Floating-Point Semantics JEP 406: Pattern Matching for switch (Preview) JEP 409: Sealed Classes

11. JEP 403: Strongly Encapsulate JDK Internals 内部APIの開発・メンテナンス性の改善のため、Java 9で導入された内部APIの隠蔽(JEP 260)がJava 16でデフォルトになり(JEP 396)、今回のJava 17で回避オプション( -illegal-access )が削除されて強制される プロジェクトによっては滅茶苦茶影響がある ここに挙げられている内部APIを利用している場合は、当該クラスが所属しているモジュール を --add-opens 等で指定して参照できるようにする必要がある。所属モジュールは jdeps コマンドで調べるか、一度実行すると "<アクセスしようとした内部クラス> (in module <内部 クラスが属するモジュール名>)" というエラーが出るのでそれで判断することができる。(トリ ッキー過ぎるので jdeps コマンドがお勧め) sun.misc.Unsafe などのクリティカルなAPIは対象外。モジュールについてはWED+DB vol.124などを参照してください。モジュール化を達成する必要はありませんが、「モジュー ル解決(Module Resolution)」について理解を深めると対応しやすい

12. JEP 391: macOS/AArch64 Port Apple Siliconへの対応 もう少し細かく言うとmacOS/AArch64におけるwrite-xor-execute memory-protectionポリ シー(メモリセグメントが実行可能であると同時に書き込み可能であることの禁止)への対応。 ユーザへのマイナスの影響はなし。

13. JEP 382: New macOS Rendering Pipeline Java 2D APIのmacOS Metal frameworkへの対応 Apple Metal APIを使ったmacOS用のJava 2Dレンダリングパイプラインの実装。元々は現在 非推奨になっているApple OpenGL APIを使っていたが、今回の時点ではこのコードは削除は されない。 内部実装の変更であり、新たなAPIが提供されるわけではない。ユーザへのマイナスの影響は なし。

14. JEP 356: Enhanced Pseudo-Random Number Generators (1/2) 疑似乱数生成(PRNG)の改善、新API( java.util.random パッケージ)の提供により以下の5 つの問題を解決 既存PRNGクラス間(Random,ThreadLocalRandom,SplittableRandom)の置換えが容易 でない PRNGオブジェクトのストリーム非対応 上記クラスの nextDouble() 等のストリーム生成メソッドがそれぞれ独立してメンテナ ンスされている SplittableRandomクラスの採用アルゴリズムに弱点があり、かつより実装が簡単で速度 が早いアルゴリズム(LXM)が誕生している これまでのJavaでは対応が難しい性質のアルゴリズムへの対応が困難 (jumpable/leapable PRNG algorithms)

15. JEP 356: Enhanced Pseudo-Random Number Generators (2/2) 以下のアルゴリズム・APIが新しく利用できる java.util.random.RandomGenerator SplittableRandomGenerator : 統計的に独立した結果が欲しいケース : 指定した数だけ離れた部分列使いたいケース LeapableRandomGenerator : jumpableよりさらに大幅に離れた数からの選出を行いた JumpableRandomGenerator いケース : Leapable + Jumpable リファクタリングが行われたが、既存API( java.util.Random 等)の互換性は保たれている ArbitrarilyJumpableRandomGenerator

16. JEP 415: Context-Specific Deserialization Filters Java 9で導入されたデシリアライズのフィルターが、開発者がプログラムしたフィルター を、JVM全体のfilter factory経由 ( ObjectInputFilter.Config.setSerialFilterFactory )で指定できるようになった フィルターの書き方は ObjectInputFilter クラスのJavaDocに詳しく記載されている 信頼できないデータに対してJavaオブジェクトのデシリアライズ処理を行う場合、生成した オブジェクトによって攻撃者が任意のクラスのコードを悪意を持って実行する可能性があ り、極めてセキュリティリスクが高い。このため、フィルタリングなどによって任意のクラ スのインスタンスがデシリアライズされないようにして実行されないようにするなどが必要 フィルターは新しく追加されたオプション jdk.serialFilter または jdk.serialFilterFactory から設定することも可能。対象クラスは --add-opens オプシ ョンなどで、アプリケーションクラスローダーからアクセス可能にする必要がある

17. JEP 412: Foreign Function & Memory API (Incubator) 簡潔に言うと、Java 14から脈々と続けられている「使いやすいJNI」を目指すプロジェク ト。(JVM外のコードを効率的に呼び出したり、non-heapメモリに安全にアクセスできる API)。JEP 389: Foreign Linker API (Incubator)とJEP 393: Foreign-Memory Access API (Third Incubator)の合体進化 今までのIncubatorモジュールを利用していた人にとっては、ネイティブコード呼び出し許可 のオプションが -Dforeign.restricted=permit から --enable-native-access=<対象モ ジュール> に変更になった等、細かい変更点が多い 変更点を追跡して確認するには以下の記事が詳しい https://blog.arkey.fr/2021/09/04/a-practical-look-at-jep-412-in-jdk17-with-libsodium/

18. JEP 414: Vector API (Second Incubator) フィードバックを受けて順調に改善 UTF-8文字のデコードなど、文字操作APIの強化 short vectorとchar配列の間で文字をコピーするメソッド追加 integral vectorとの符号なし比較のための新しいベクター比較演算子追加 byte vectorとboolean配列の変換APIを追加 Intel Short Vector Math Library (SVML) を使用した演算サポート Intel x64、ARM NEONにおけるパフォーマンス向上 次のJava 18でThird Incubatorになり(つまり標準機能にならない)、4つあったFuture workの 内1つが解決され、1つ増えている

19. JEP 306: Restore Always-Strict Floating-Point Semantics 浮動小数点計算が常に厳密になり、関連標準ライブラリ( java.lang.{Math,StrictMath} など)のメンテナンス性改善、JVM動作の一貫性が保たれるようになった 多くのユーザにとっては影響なし。非厳密な計算を強制する方法はなく、動作非互換性が生 じるプラットフォームも極僅か。JVMプロセスを動作させているCPUがSSE2以降をサポート していない場合は負荷が発生するかもぐらい。

20. [beta]

JEP 406: Pattern Matching for switch (Preview) (1/3)

Preview機能だが、ついにswitch文/式でpattern matchingが使えるようになった
static String message(Object o) {
return switch(o) {
case String s -> s;
case Integer i -> "Your input is number(%d)".formatted(i);
// null
case null, Double d -> "Double or null";
// (Object
) default
// "incomplete"
default -> o.toString();
};
}

のハンドリングもサポート
の継承クラス全部列挙は現実的に不可能なので
節がないと
「すべての可能な入力値をカバーしていません」でエラー

jshell> message(1)
$2 ==> "Your input is number(1)"

21. [beta]

JEP 406: Pattern Matching for switch (Preview) (2/3)
case String s -> s;
case null, Double d -> "Double or null";
jshell> message(1.0)
$3 ==> "Double or null"
jshell> message(null)
$4 ==> "Double or null"
jshell> message("null")
$5 ==> "null"

勿論nullのハンドリングがなければNPEが発生する
jshell> message(null)
|
java.lang.NullPointerException
|
at Objects.requireNonNull (Objects.java:208)
|
at message (#13:2)
|
at (#14:1)

例外

22. [beta]

JEP 406: Pattern Matching for switch (Preview) (3/3)

また以下のようなガードパターンやカッコつきパターンがサポートされた
static String message(Object o) {
return switch(o) {
case String s && (s.length() >= 1) -> s;
case String s -> "empty message";
default -> o.toString();
};
}
jshell> message("a")
$8 ==> "a"
jshell> message("")
$9 ==> "empty message"

Previewなので実行時に --enable-preview オプションが必要

23. JEP 409: Sealed Classes JDK 15(JEP 360)でプレビュー導入されたシールクラスが標準機能に昇格。 JDK 16からの変更点はなし。 public sealed interface Point permits Shape, Circle, Square{ ... } インターフェース(※クラスも可)を(直接)継承・実装できるインターフェース・クラス を Shape 、 Circle 、 Square のみに制限できる。今までは継承可かfinalにして不可にする 二極しかなかった Point

24. Deprecations & Removals Deprecations JEP 398: Deprecate the Applet API for Removal JEP 411: Deprecate the Security Manager for Removal Removals JEP 407: Remove RMI Activation JEP 410: Remove the Experimental AOT and JIT Compiler

25. JEP 398: Deprecate the Applet API for Removal Java 9で非推奨化した(JEP 289)Applet APIを削除のための非推奨化 @Deprecated(since="9") -> @Deprecated(since="9", forRemoval=true) java.applet.Applet java.applet.AppletStub java.applet.AppletContext java.applet.AudioClip javax.swing.JApplet java.beans.AppletInitializer java.beans.Beans javax.swing.RepaintManager javax.naming.Context

26. JEP 411: Deprecate the Security Manager for Removal Java 1.0から採用され主にAppletを動かす際のサンドボックスなどで利用されていたSecurity Managerだったが、サーバーサイドではほとんど使われず、Applet API削除の流れとともに 削除のための非推奨となった。 使っている場合は警告が出る。起動時にSecurity Managerを有効にしておらず、実行中に後 から動的に有効にした場合でも警告が出る( System::setSecurityManager が呼び出される 度に出る)

27. JEP 407: Remove RMI Activation Java 8で必須でなくなり、Java 15で非推奨化した(JEP 385) RMI Activationを削除。 RMI Activationは rmid と呼ばれるRMIデーモンにRMIサービスを登録し、必要に応じてリモ ートオブジェクトをここから生成するための仕組み。セキュリティ(WAF、Authentication 等々)などは最新のWeb技術で達成され、RMI Activationにはないlazy instantiationもコンテ ナなどを組み合わせて達成できる状況なので、もやこれを採択する必要性は殆どない状態 RMIそのものは非推奨化されておらず、削除もされない

28. JEP 410: Remove the Experimental AOT and JIT Compiler Java 9で実験導入されたAhead-of-Timeコンパイラ( jaotc ツール)(JEP 295)と、Java 10で 実験導入されたJust-in-TimeコンパイラGraal(JEP 317)が削除された。 ただし、JVM compiler interface (JMVCI)は継続して残される ちなみにJDK 16のOracle OpenJDK binaryからも削除されている

29. Other noteworthy changes (1/3) JEP以外で、個人的に気になっている変更・改善をピックアップ JDK-8229517: ロギングの非同期出力。 -Xlog:async で有効化、バッファリングして 出力する。中間バッファが枯渇すると破棄されるので -XX:AsyncLogBufferSize= <bytes> を使用してサイズを調整する。少なくとも一部のGC Loggingはsafepointで実 行されるため、Diskの問題などでロギングが長大化するとSTWも長大化する問題があっ た。これはこの問題を解消あるいは軽減できる見込み JDK-8217633: TLS 1.3がデフォルト化。これまではTLS 1.2がデフォルトだった JDK-8243287: sun.misc.Unsafe::defineAnonymousClass 削除。今後はHidden Class JFR: JDK Flight Recorder New events: jdk.SystemGC (JDK-8003216)、 jdk.GCLocker (JDK8259808)、 jdk.Deserialization (JDK-8268316)、5 Container level events(JDK-8203359) jfr configure --interactive : プロファイリング設定を対話モードで作成

30. Other noteworthy changes (2/3) GC関係のJEPはないが313件の改善がある (JBS) 性能改善は至る所で行われてる よく使うであろうG1 GCとZGCに絞って紹介 ZGC See https://malloc.se/blog/zgc-jdk17 JDK-8268372: 常に固定数のGCThreadを利用していたが可能な限り少なくなるよう動 的に変更するようになった ( UseDynamicNumberOfGCThreads ) JDK-8265136: JMX GarbageCollectorMXBeans がGCサイクルとPause情報を提供 JDK-8260267: マーキングフェーズのメモリ使用量を大幅に削減

31. Other noteworthy changes (3/3) G1GC JDK-8257774: Evacuation failureによる長いpauseを回避するために通常の定期的に実 行されるGCとは別に、予防的にヒープが充分にある(ライブオブジェクトのコピーが確 実にできる)タイミングで実施するMinor GCの一種を導入 デフォルトで有効。 G1 Preventive Collection のログを確認し、問題があれ ば -XX:-G1UsePreventiveGC で無効化できる 通常GCのトリガー閾値の過度なチューニングを避けれるようになるかも JDK-8262068: MarkSweepDeadRatio オプションを用いたG1 Full GC効率化 G1 Full GCのコンパクション対象リージョンのSurvival ratioとして利用する。例え ば -XX:MarkSweepDeadRatio=5 (デフォルト値)とした場合、生存オブジェクト割 合が95%以上の場合、そのリージョンは(コンパクションしたところで返ってくるメ モリは少ないと想定できるので)コンパクション対象外になる

32. Java 18 4 Java Enhancement-Proposals Project page: https://openjdk.java.net/projects/jdk/18/ JBS 78 Compatibility & Specification Reviews JBS

33. JEP 400: UTF-8 by Default 標準Java APIのcharsetがUTF-8がデフォルトになった 現在使っているJavaのcharsetを確認するには以下のコマンドを実行する java -XshowSettings:properties -version 2>&1 | grep file.encoding 日本語環境の の場合 # Windows C:\Users\ykubota\workspace > .\jdk-17\bin\java -XshowSettings:properties -version 2>&1 | grep file.encoding file.encoding = MS932 もし、UTF-8がデフォルトでない場合、滅茶苦茶影響がある可能性がある。表示が文字化け する以外にも、複数のバージョンが異なるJavaを利用していた場合、UTF-8をサポートして いないJavaで生成したファイルをJava 18で正しく読み込めないといったケースがあり得る 先ずは、現在使っているJavaで -Dfile.encoding=UTF-8 を指定して動作確認を行うことか ら始めることを推奨

34. JEP 408: Simple Web Server テスト、開発、デバッグのみを目的とした最小限の機能で、コマンドラインツールからすぐ に使える静的HTTPファイルサーバを提供 元々JDKにはhttpserverがあったが使いづらく、あまりメンテナンスもされていなかった $ java -m jdk.httpserver $ java -m jdk.httpserver --bind-address 0.0.0.0 --port 8080 --directory $(pwd) --output verbose

35. JEP 413: Code Snippets in Java API Documentation (1/2) JavaDocでコードスニペットが対応。 Doc内にスニペットを埋め込む(Inline snippet) /** * The following code shows how to use {@code Optional.isPresent}: * {@snippet : * if (v.isPresent()) { * System.out.println("v: " + v.get()); * } * } */ 外部のスニペットを参照する(External snippet) /** * The following code shows how to use {@code Optional.isPresent}: * {@snippet file="ShowOptional.java" region="example"} */

36. [beta]

JEP 413: Code Snippets in Java API Documentation (2/2)

外部スニペット参照元

public class ShowOptional {
void show(Optional<String> v) {
// @start region="example"
if (v.isPresent()) {
System.out.println("v: " + v.get());
}
// @end
}
}

この他、特定の文字を強調するための @highlight タグや、実コードから一部書き換えたい
場合に使う @replace タグ、リンクを張るための @link タグなどをサポート
Java以外のファイルを参照した場合、Inline snippetの場合は @snippet タグの後に
lang=properties 等のように指定することでSyntax Hightligtがサポートされる

37. JEP 417: Vector API (Third Incubator) ARM Scalar Vector Extension (SVE) プラットフォームをサポート ハードウェアでマスキングをサポートするアーキテクチャにおいて、マスクを受け取る ベクトル演算のパフォーマンスを向上

38. Head toward Java 17 and Java 18 KUBOTA Yuji LINE Corporation JJUG CCC 2021 Fall