Successfully reported this slideshow.

Head toward Java 13 and Java 14 #jjug

616 views

Published on

New features and APIs on Java 13 and Java 14. OpenJDK forks trend.

Published in: Technology
  • Be the first to comment

Head toward Java 13 and Java 14 #jjug

  1. 1. HeadtowardJava13andJava14 KUBOTAYuji(@sugarlife) LINECorporation JJUGCCC2019Fall(2019/Nov/23)
  2. 2. KUBOTAYuji(@sugarlife) IcedTeacommitter/OpenJDKAuthor/DukeChoiceAward2016 Winner WEB+DBで「DivetoJava」連載中 https://www.slideshare.net/YujiKubota/ 好きなパッケージは sun.jvm.hotspot 2
  3. 3. 本セッションで話すこと Java13から利用できる機能と変更点 Java14以降から利用できる可能性がある機能と変更点 OpenJDKForksの動向 3
  4. 4. 前置き 本資料は jdk.java.net からダウンロードできる JDK 13.0.1 およ び JDK 14 (build 21) で極力動作確認していますが、全ての確認はで きていませんのでコードを修正する前に動作確認してください 実装は hg.openjdk.java.net/jdk-updates/jdk13u および jdk/jdk で確認しています 4
  5. 5. Java13 5JavaEnhancementProposals(JEP) 142Compatibility&SpecificationReviews(CSR) 712FixedEnhancementTickets 1378FixedBugTickets Java14 8+5(inreview)JavaEnhancementProposals(JEP) 102Compatibility&SpecificationReviews(CSR) 455FixedEnhancementTickets 744FixedBugTickets 5
  6. 6. JEPs(13) 350:DynamicCDSArchives 351:ZGC:UncommitUnusedMemory 353:ReimplementtheLegacySocketAPI 354:SwitchExpressions(Preview) 355:TextBlocks(Preview) 6
  7. 7. 350:DynamicCDSArchives 重要度:★☆☆ CDS=ClassDataSharing。共通的なクラスや文字列などを複数プ ロセスで共有する機能 アプリケーション実行終了時にロードしたクラスを動的にアーカイ ブする -XX:ArchiveClassesAtExit=/path/to/archiveFile 後足しできないので異常系を含めてCDSに含まれるべきクラスをロ ードする全パターン通る必要がある 7
  8. 8. 351:ZGC:UncommitUnusedMemory 重要度:★☆☆ ZGCが未使用のメモリをアンコミットしてOSに返すようになった Xmsは下回らないようになってるので、XmxとXmsが等しければ この機能は自動的に無効になる -XX:-ZUncommit を設定することで無効にすることも可能。デフ ォルトは有効 ZPage‑>ZPageCache(ZPageinpagecase)‑ZUncommitDelay‑> uncommitted&returned -XX:ZUncommitDelay=<seconds> デフォルトは5分。 ZGCは引き続きExperiment機能 ( UnlockExperimentalVMOptions ) 8
  9. 9. 353:ReimplementtheLegacySocketAPI 重要度:★☆☆ SocketAPI( java.net.Socket や java.net.ServerSocket )の内 部実装が変わった 旧実装は -Djdk.net.usePlainSocketImpl を指定すれば使用可能 -Xlog:class+load=level を設定してどのクラスがinstantiateさ れるか見てみると変更箇所がわかる java.net.PlainSocketImpl から sun.nio.ch.NioSocketImpl に変更されてる 旧実装はレガシーなSPI(SupportProviderInterface)機構のJavaとCの実 装で、スレッドスタックをI/Oバッファとして利用したり、非同期処理を nativeなデータ構造で行っていたりと移植性等が好ましくなかった 今後ユーザモードなスレッド(Fiber)が導入されることもあり、ネイティ ブな世界でブロックすることなく停止(park)できるように変更された 9
  10. 10. 354:SwitchExpressions(Preview) 重要度:★☆☆ Preview機能は --enable-preview を付ける必要がある(java、 javac、jshell全部) 戻り値を示すステートメントが break から yield に変更された Switch"文"は break Switch"式"は yield 10
  11. 11. String releaseDate = switch (version) { case java12: // Java 12での書き方 break "2019/03/19" case java13: // Java 13以降での書き方 yield "2019/09/17"; default: throw new IllegalArgumentException(); }; 11
  12. 12. 355:TextBlocks(Preview) 重要度:★☆☆ 待望のヒアドキュメント(ただしプレビュー機能) 関連してStringクラスの拡張も同時に行われてる JDK‑8203630:String::formatted(Preview) ヒアドキュメントに対するフォーマット文字列 JDK‑8223776:String::stripIndent(Preview) (ヒアドキュメントにも対応した)インデント削除 JDK‑8223781:String::translateEscapes(Preview) エスケープシーケンスの解釈を行う これらのAPIはPreviewなので非推奨かつ削除フラグが最初から 有効になっている @Deprecated(forRemoval=true) いつでも削除や修正が行えるようにされている 12
  13. 13. String java13 = """ { "releaseDate": "2019/09/17", "JSR": 388 } """; String java12 = "{n" + ""releaseDate": "2019/03/19",n"+ ""JSR": 386n" + "}n"; 13
  14. 14. ヒアドキュメントのフォーマット構文 String java13 = """ { "releaseDate": "%s", "JSR": %d } """.formatted(releaseDate, jsr); String.format(ヒアドキュメント, Object... args) でも可能だが冗 長な表現であるため導入された 14
  15. 15. Q:"JJUG¥nCCC¥n"になるのはどれでしょう """JJUG CCC""".stripIndent() """ JJUG CCC """.stripIndent() """ JJUG CCC """.stripIndent() """ JJUG CCC #(CCCの後ろにスペースがある) """.stripIndent() """ JJUG CCC """ 15
  16. 16. APIs すべてのAPI差分はJSR388(Java13のJavaSpecificationRequest)の 「FinalReleaseAnnex2forEvaluation」に記載されている あるいはこのDraftを書いたメンテナのリポジトリから確認もできる: http://cr.openjdk.java.net/~iris/se/13/build/latest/diffsFrom12%2B32/ 16
  17. 17. RemovedAPIs Runtime#traceInstructions(boolean) Runtime#traceMethodCalls(boolean) この2つは実装がなかったので実質何も変わらない あるフラグが有効になるのだがどこもそれを参照していない… willRemoved javax.security.certのクラスが削除フラグ( forRemoval=true ) Java9から非推奨になっておりjava.security.certに移行した javax.net.sslにあるgetPeerCertificateChain()メソッドに削除フラグ 上で削除されるクラスを返してるため同時に削除される 代わりにgetPeerCertificates()メソッドを使う 17
  18. 18. bitnotableAddedAPIs Unicode12.1サポート Character.UnicodeBlock 、 Character.UnicodeScript にUnicode12.1で追加されたブロック、スクリプトが加わった java.lang.Character のJavaDocを確認するとサポートさ れているUnicodeのバージョンが確認できる java.nio.Buffer#slice java.nio.{Byte,Char,Double,Float,Int,Long,Short}# {get,put,slice} java.nio.MappedByteBuffer#force java.nio.file.FileSystems#newFileSystem 18
  19. 19. JDK‑5071718:AddByteBuffer.slice(intindex,intlength) Java5時代から提案されていたBufferのAPIがついに追加。 今までは引数なしの slice() で現在の位置から限度まで取り出すしか なかったが、位置と長さを指定することが可能になった 19
  20. 20. JDK‑5029431:Addabsolutebulkputandgetmethods Java1.4時代から提案されていた java.nio.ByteBuffer の実装クラス に slice と同様に put 、 get メソッドが追加された 以下はByteBufferの例、実装クラスごとに第2引数の型が異なる。(この ため親abstractclassであるBufferクラスに追加できなかった) get(int index, byte[] dst) get(int index, byte[] dst, int offset, int length) put(int index, byte[] src) put(int index, byte[] src, int offset, int length) 今までは指定した位置から読む(get)/書く(put)か、indexを指定して1バ イト読む/書くしかできなかったが、新たに加わったこれらのメソッドで 第2引数に指定した配列に柔軟に読み書きが行えるようになった 20
  21. 21. JDK‑8222261:MappedByteBuffer.forcemethodtospecify range 今までは引数なしで全範囲を強制的にファイルに書き出すしかなかった が、これも同じく位置と長さを指定して強制的にファイルに書き出せる ようになった force(int index, int length) この調子でunmmapedするAPIも追加して欲しい 21
  22. 22. JDK‑8219793:AddFileSystems.newFileSystem(Path, Map<String,?>)method ZIPファイルなどを1つのFileSystemとみなして操作するのによく使われ るが、このinstantiationに Path でファイルの位置を指定できるようにな った。これまでは URI か ClassLoader が必須だったため、より簡単に 利用しやすくなっている 22
  23. 23. Otherenhancements JDK‑8218131:Adddumptofilesupportforjmap‑histo JDK‑8219257:Add‑‑strip‑native‑debug‑symbolsjlinkplugin 特定OSでdebugsymbolを含めてファイルサイズが大きくなっ た問題の修正 JDK‑8223852:Add‑XX:MinHeapSizeflagtosettheminimum heapsize -Xms は正確には初期サイズであり最小サイズではない 23
  24. 24. JEPs(14) 345:NUMA‑AwareMemoryAllocationforG1 349:JFREventStreaming 352:Non‑VolatileMappedByteBuffers 358:HelpfulNullPointerExceptions 361:SwitchExpressions(Standard) 363:RemovetheConcurrentMarkSweep(CMS)Garbage Collector 364:ZGConmacOSs 367:RemovethePack200ToolsandAPI 24
  25. 25. Inreview 305:PatternMatchingforinstanceof(Preview) 343:PackagingTool(Incubator) 359:Records(Preview) 368:TextBlocks(SecondPreview) 366:DeprecatetheParallelScavenge+SerialOldGC Combination 365:ZGConWindows 25
  26. 26. 345:NUMA‑AwareMemoryAllocationforG1 Java7時代(2011年)に一度提案されていたが仕切り直し +XX:+UseNUMA NUMAnodesを意識してheapregionの配置を行う 初期処理時にNUMAnodeごとにheapregionを均等に配置 オブジェクト生成時は同じNUMAnodeに配置されるように実 行スレッドが属しているnodeから優先的に選択する 空きがなければ距離の近いnodeに配置する、など Humongousregionは対象外 26
  27. 27. 349:JFREventStreaming これまでディスクに書き込まれたバイナリデータから解析やモニタリン グを行う必要があったが、ストリーミングで流し込むことが可能になる 今まで何故なかったのかというぐらい便利。性能次第ではJMXや一部の ロギングをこれに置き換えることも十分にあり得る ところでJavaMissionControlの7.0GAはまだですか 2019/0X/YZGeneralAvailability(delayed) 27
  28. 28. 352:Non‑VolatileMappedByteBuffers NVM向けの MappedByteBuffer API追加。 28
  29. 29. 358:HelpfulNullPointerExceptions 今まではある行がNPEを出したといった情報しかJVMは提供してこなか った。このため以下のようなコードがNPEを出した場合はどこに問題が あるのかが分からない a[i][j][k] = b.l; そこで、次のようにNPEのエラーメッセージにて発生状況と箇所を明確 に返すことで、このような不明瞭さを排除する Cannot load from object array because 'a[i][j]' is null. Cannot read field 'l' because 'b' is null. 全ての処理はbytecodeで記述可能なので、それに応じてメッセージ出力 を変えている(changeset)。全てのローカル変数の情報も含めて出力する にはclassfileにdebuginformationを含める必要がある( javac -g ) 29
  30. 30. 361:SwitchExpressions(Standard) SwitchExpressionがついに標準機能へ、現時点では大きな変更点はない 30
  31. 31. 363:RemovetheConcurrentMarkSweep(CMS)Garbage Collector 非推奨になっていたCMSGCがついにソースコードから削除された (changeset) 31
  32. 32. 365:ZGConmacOSs Linux用であったZGCがmacOSsにも移植 Windowsへの移植も一時期Java14の候補に挙がったが、流石に無理だ ったのかすぐに外された講演日直前で候補(inreview)になりました 32
  33. 33. 367:RemovethePack200ToolsandAPI pack200 ツール、及び非推奨になっていた関連APIが削除される 33
  34. 34. ここからinreview 34
  35. 35. 305:PatternMatchingforinstanceof(Preview) Before if (obj instanceof Double) { Double d = (Double) obj; // d を使った処理 } After if (obj instanceof Double d) { // d を使った処理 } switch でも同じように書ける switch (obj) { case Integer i: // intの時にやらせたい処理 case Double d: // doubleの時にやらせたい処理 } 35
  36. 36. 343:PackagingTool(Incubator) JavaFXjavapackagerをベースにパッケージングツールを提供 deb/rpm pkg/dmg msi/exe の全てをカバーしつつ、起動時に渡すパラメータをパッケージング時に 指定可能、API(ToolProvider)が生えててプログラマブルと盛りだくさん 最終的には、 jlink で最適化・最小化された実行イメージを作成し、こ のパッケージツールでインストーラを作る流れになることを目指してい る 36
  37. 37. 359:Records(Preview) データクラス。乱暴に言うと構造化されたtuplesのようなもの。 Specificationdraft {ClassModifier} record TypeIdentifier [TypeParameters] RecordComponent { , RecordComponent }   [SuperInterfaces] RecordBody record NonEmptyString(int x, String s) {} 37
  38. 38. final class NonEmptyString implements java.lang.Record { // コンポーネントと同名同型のprivate final fieldが作られ // これを格納するpublicなコンストラクタが作られる private final int x; private final String s; public NonEmptyString(int x, String s) { this.x = x; this.s = s; } // コンポーネントと同名のアクセサが作られる public int x() { return x; } public String s() { return s; } // コンポーネントを適切に扱うよう下記メソッドが自動的に実装 // 自分で実装もできるが利点(shallowly-immutable, // well-behaved)を破らないように注意が必要 public boolean equals() { (snip) } public int hashCode() { (snip) } public String toString() { (snip) } } 38
  39. 39. データクラスの悩みどころであるコンポーネントの検証や正規化がコン ストラクタ(canonicalconstructor)として書ける record NonEmptyString(int x, String s) { public NonEmptyString { // Stringコンポーネントをnon emptyに正規化 if ( s == "" ) { this.s = "JVM is treasure."; } else { this.s = s; } } } 39
  40. 40. 368:TextBlocks(SecondPreview) 改行( )と空白( s )を柔軟に制御できるよう2つの新たなエスケープシ ーケンスが追加される TextBlock内で末尾に を付けて改行するとその改行は無視される s は u0020 (空白)に変換される。前後の余分な空白が削除され てから変換されるため、結果として s と文字列の間にある空白が 削除されることを防ぐことができる 40
  41. 41. #普通のText Blocks """ JJUG CCC """ => "JJUG¥nCCC¥n" #本来は一行で書ききれないめっちゃ長い文章を意図的に改行する時に使う """ JJUG CCC """ => "JJUG CCC" #各行辺りの文字数を制御したい時などに使う """ JJUG s CCC s """ => "JJUG ¥nCCC ¥n" 41
  42. 42. 366:DeprecatetheParallelScavenge+SerialOldGC Combination Young領域はParallelでOld領域はSerialでGCを実行するという組み合わ せが非推奨化された -XX:+UseParallelGC -XX:-UseParallelOldGC もちろん、他の組み合わせ、例えば両方ParallelまたはSerialは継続 42
  43. 43. 365:ZGConWindows Linux用であったZGCがWindowsにも移植 43
  44. 44. OpenJDKForks OpenJDKはリリース後に各団体が長期間メンテナンスを行う予定の LTS(LongTermSupport、JDK11)のバージョンと、半年間のメンテナ ンスが行われるそれ以外(non‑LTS、JDK9、10、12)バージョンがある と、JDK9の時点で言われていたが実際はどうなのか答え合わせをして いこう 44
  45. 45. OpenJDK 厳密にはメンテナンス期間は確定していない。OpenJDKコミュニティの メーリングリストでメンテナンス終了の通知が行われ、メンテナンスを 引き継ぐコミュニティなどが現れないとそのまま終了となる JDK9、JDK10、JDK12は引き継ぎ先が現れず終了 JDK11:リポジトリは jdk-updates/jdk11u 投票を経て、RedhatのAndrewHaleyがMaintenancelead引継 Oracleの貢献ポリシーはここ。OracleOpenJDK11の配信 (http://jdk.java.net)も当初の予定通り6ヶ月で停止された 脆弱性は非公開グループ(OpenJDKVulnerabilityGroup)で共 有・議論され、重要な更新は四半期ごとに行われると宣言 commitlogやJBSを見る限りbackportは適切に行われている JDK13はまだ半年間経っていないのでメンテナンスが行われてい る。リポジトリは jdk-updates/jdk13u 45
  46. 46. EclipseOpenJ9 https://www.eclipse.org/openj9/ JDK部分ではなくJVM(JavaVirtualMachine)のオープン実装。JDK部分 にOpenJDKを利用したバイナリがAdoptOpenJDKコミュニティで配布 されている このためJDK部分のメンテナンスは実質AdoptOpenJDKに準じる。JVM 部分は実装そのものが異なるためバグや脆弱性は独自にEclipseプロジェ クトで管理されている 46
  47. 47. AdoptOpenJDK ビルドツールはgithubで管理されており、個人でもローカルまたは Docker上でビルドが可能。コミュニティのインフラもgithubで管理され ている。丁寧にREADMEで解説しているので必見 ビルド元は github.com/AdoptOpenJDK/openjdk-jdk<NN>u (各Javaバ ージョン)と github.com/AdoptOpenJDK/openjdk-jdku (開発の最新リ ポジトリ)だが、これはAdoptOpenJDKJenkinsで git-hg により OpenJDKコミュニティのリポジトリ jdk-updates/jdk<NN>u と jdk/jdk をミラーリングしている。結果としてJava11は jdk- updates/jdk11u をベースにしており、メンテナンスはOpenJDKに準 じる 47
  48. 48. AmazonCorretto 公式リポジトリ:https://github.com/corretto 独自パッチ(ドキュメントより) https://docs.aws.amazon.com/corretto/latest/corretto‑11‑ ug/patches.html https://docs.aws.amazon.com/corretto/latest/corretto‑8‑ ug/patches.html Java11のリポジトリではupstreamでタグ打ちされたタイミングでmerge しているようだがsquashされてて一見では確認不可能かつ、upstream がリポジトリ上のコードから確認できず不明。mergeもPRでmergeパタ ーンと直接Pushパターンがある 独自パッチは develop ブランチなどのcommitlogから確認ができる 48
  49. 49. RedHatOpenJDK LinuxDistribution提供のopenjdkパッケージは提供元のパッケージソー ス、rpmパッケージであればRPMS(SPEC)を確認する Fedora RPMSを管理しているgitリポジトリが公開されている Fedora31(latest)のOpenJDK11のRPMSはここ OpenJDKのshenandoahプロジェクトのjdk11リポジトリをベース にicedtea8のtapsetや独自パッチ(Crashバグ修正、暗号ポリシー、 SunJSSE周りの変更(SunPKCS11Provider等)など)を追加している 49
  50. 50. CentOS Fedora同様RPMSを管理しているgitリポジトリで確認可能 CentOS8(latest)のOpenJDK11 OpenJDKのshenandoahプロジェクトのjdk11リポジトリをベース (※)にicedtea8のtapsetや独自パッチ(Fedoraとほぼ同じ)を追加 ※: update_package.sh によりベースとなるコードのtarballを入手して いるが、肝心のスクリプトがリポジトリ上にない。同名のファイルが FedoraのRPMS管理リポジトリにありかつ同一人物がメンテナであるた め、そこからの推測 50
  51. 51. Shenandoahプロジェクト ShenandoahはGCの一つでOpenJDKコミュニティではまだExperiment だが、RedHatがメインで開発しているshenandoahプロジェクトでは標 準機能になっており、ここから入手してる。changesetを確認する限り バックポートはfork元のjdk‑updates/jdk11と同一内容で実施されている このため、FedoraもCentOSもメンテナンス期間は(そもそもメンテナン スリードがRedHatだが)OpenJDKコミュニティに準じる RedHat RedHatはSubscription契約した上でsrcパッケージ(java‑11‑openjdk‑ src)のRPMSを確認しましょう icedtea WebStartの代替であるIcedtea‑WebやJava7とJava8を提供している チェンジログ:http://blog.fuseyism.com/ リポジトリ:http://icedtea.classpath.org/hg/ 51
  52. 52. Ubuntu パッケージングソースがpublicなgitリポジトリで管理されており、 openjdk‑11パッケージはここで管理されている debian/watchでチェックしているベースとなるupstreamはOpenJDKコ ミュニティの jdk-updates/jdk11u 。このためメンテナンス期間は OpenJDKコミュニティに準じる これに独自パッチ(3.0(quilt))としてSunJSSE(PKCS11)関係のほか、使 用するライブラリ、一部環境のスレッドスタックデフォルト値などを変 更している 52
  53. 53. HeadtowardJava13andJava14 KUBOTAYuji(@sugarlife) LINECorporation JJUGCCC2019Fall(2019/Nov/23)

×
Save this presentation