HeadtowardJava13andJava14
KUBOTAYuji(@sugarlife)
LINECorporation
JJUGCCC2019Fall(2019/Nov/23)
KUBOTAYuji(@sugarlife)
IcedTeacommitter/OpenJDKAuthor/DukeChoiceAward2016
Winner
WEB+DBで「DivetoJava」連載中
https://www.slideshare.net/YujiKubota/
好きなパッケージは sun.jvm.hotspot
2
本セッションで話すこと
Java13から利用できる機能と変更点
Java14以降から利用できる可能性がある機能と変更点
OpenJDKForksの動向
3
前置き
本資料は jdk.java.net からダウンロードできる JDK 13.0.1 およ
び JDK 14 (build 21) で極力動作確認していますが、全ての確認はで
きていませんのでコードを修正する前に動作確認してください
実装は hg.openjdk.java.net/jdk-updates/jdk13u および jdk/jdk
で確認しています
4
Java13
5JavaEnhancementProposals(JEP)
142Compatibility&SpecificationReviews(CSR)
712FixedEnhancementTickets
1378FixedBugTickets
Java14
8+5(inreview)JavaEnhancementProposals(JEP)
102Compatibility&SpecificationReviews(CSR)
455FixedEnhancementTickets
744FixedBugTickets
5
JEPs(13)
350:DynamicCDSArchives
351:ZGC:UncommitUnusedMemory
353:ReimplementtheLegacySocketAPI
354:SwitchExpressions(Preview)
355:TextBlocks(Preview)
6
350:DynamicCDSArchives
重要度:★☆☆
CDS=ClassDataSharing。共通的なクラスや文字列などを複数プ
ロセスで共有する機能
アプリケーション実行終了時にロードしたクラスを動的にアーカイ
ブする
-XX:ArchiveClassesAtExit=/path/to/archiveFile
後足しできないので異常系を含めてCDSに含まれるべきクラスをロ
ードする全パターン通る必要がある
7
351:ZGC:UncommitUnusedMemory
重要度:★☆☆
ZGCが未使用のメモリをアンコミットしてOSに返すようになった
Xmsは下回らないようになってるので、XmxとXmsが等しければ
この機能は自動的に無効になる
-XX:-ZUncommit を設定することで無効にすることも可能。デフ
ォルトは有効
ZPage‑>ZPageCache(ZPageinpagecase)‑ZUncommitDelay‑>
uncommitted&returned
-XX:ZUncommitDelay=<seconds> デフォルトは5分。
ZGCは引き続きExperiment機能
( UnlockExperimentalVMOptions )
8
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
354:SwitchExpressions(Preview)
重要度:★☆☆
Preview機能は --enable-preview を付ける必要がある(java、
javac、jshell全部)
戻り値を示すステートメントが break から yield に変更された
Switch"文"は break
Switch"式"は yield
10
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
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
String java13 = """
{
"releaseDate": "2019/09/17",
"JSR": 388
}
""";
String java12 = "{n" +
""releaseDate": "2019/03/19",n"+
""JSR": 386n" +
"}n";
13
ヒアドキュメントのフォーマット構文
String java13 = """
{
"releaseDate": "%s",
"JSR": %d
}
""".formatted(releaseDate, jsr);
String.format(ヒアドキュメント, Object... args) でも可能だが冗
長な表現であるため導入された
14
Q:"JJUG¥nCCC¥n"になるのはどれでしょう
"""JJUG
CCC""".stripIndent()
"""
JJUG
CCC """.stripIndent()
"""
JJUG
CCC
""".stripIndent()
"""
JJUG
CCC #(CCCの後ろにスペースがある)
""".stripIndent()
"""
JJUG
CCC
"""
15
APIs
すべてのAPI差分はJSR388(Java13のJavaSpecificationRequest)の
「FinalReleaseAnnex2forEvaluation」に記載されている
あるいはこのDraftを書いたメンテナのリポジトリから確認もできる:
http://cr.openjdk.java.net/~iris/se/13/build/latest/diffsFrom12%2B32/
16
RemovedAPIs
Runtime#traceInstructions(boolean)
Runtime#traceMethodCalls(boolean)
この2つは実装がなかったので実質何も変わらない
あるフラグが有効になるのだがどこもそれを参照していない…
willRemoved
javax.security.certのクラスが削除フラグ( forRemoval=true )
Java9から非推奨になっておりjava.security.certに移行した
javax.net.sslにあるgetPeerCertificateChain()メソッドに削除フラグ
上で削除されるクラスを返してるため同時に削除される
代わりにgetPeerCertificates()メソッドを使う
17
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
JDK‑5071718:AddByteBuffer.slice(intindex,intlength)
Java5時代から提案されていたBufferのAPIがついに追加。
今までは引数なしの slice() で現在の位置から限度まで取り出すしか
なかったが、位置と長さを指定することが可能になった
19
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
JDK‑8222261:MappedByteBuffer.forcemethodtospecify
range
今までは引数なしで全範囲を強制的にファイルに書き出すしかなかった
が、これも同じく位置と長さを指定して強制的にファイルに書き出せる
ようになった
force(int index, int length)
この調子でunmmapedするAPIも追加して欲しい
21
JDK‑8219793:AddFileSystems.newFileSystem(Path,
Map<String,?>)method
ZIPファイルなどを1つのFileSystemとみなして操作するのによく使われ
るが、このinstantiationに Path でファイルの位置を指定できるようにな
った。これまでは URI か ClassLoader が必須だったため、より簡単に
利用しやすくなっている
22
Otherenhancements
JDK‑8218131:Adddumptofilesupportforjmap‑histo
JDK‑8219257:Add‑‑strip‑native‑debug‑symbolsjlinkplugin
特定OSでdebugsymbolを含めてファイルサイズが大きくなっ
た問題の修正
JDK‑8223852:Add‑XX:MinHeapSizeflagtosettheminimum
heapsize
-Xms は正確には初期サイズであり最小サイズではない
23
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
Inreview
305:PatternMatchingforinstanceof(Preview)
343:PackagingTool(Incubator)
359:Records(Preview)
368:TextBlocks(SecondPreview)
366:DeprecatetheParallelScavenge+SerialOldGC
Combination
365:ZGConWindows
25
345:NUMA‑AwareMemoryAllocationforG1
Java7時代(2011年)に一度提案されていたが仕切り直し
+XX:+UseNUMA
NUMAnodesを意識してheapregionの配置を行う
初期処理時にNUMAnodeごとにheapregionを均等に配置
オブジェクト生成時は同じNUMAnodeに配置されるように実
行スレッドが属しているnodeから優先的に選択する
空きがなければ距離の近いnodeに配置する、など
Humongousregionは対象外
26
349:JFREventStreaming
これまでディスクに書き込まれたバイナリデータから解析やモニタリン
グを行う必要があったが、ストリーミングで流し込むことが可能になる
今まで何故なかったのかというぐらい便利。性能次第ではJMXや一部の
ロギングをこれに置き換えることも十分にあり得る
ところでJavaMissionControlの7.0GAはまだですか
2019/0X/YZGeneralAvailability(delayed)
27
352:Non‑VolatileMappedByteBuffers
NVM向けの MappedByteBuffer API追加。
28
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
361:SwitchExpressions(Standard)
SwitchExpressionがついに標準機能へ、現時点では大きな変更点はない
30
363:RemovetheConcurrentMarkSweep(CMS)Garbage
Collector
非推奨になっていたCMSGCがついにソースコードから削除された
(changeset)
31
365:ZGConmacOSs
Linux用であったZGCがmacOSsにも移植
Windowsへの移植も一時期Java14の候補に挙がったが、流石に無理だ
ったのかすぐに外された講演日直前で候補(inreview)になりました
32
367:RemovethePack200ToolsandAPI
pack200 ツール、及び非推奨になっていた関連APIが削除される
33
ここからinreview
34
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
343:PackagingTool(Incubator)
JavaFXjavapackagerをベースにパッケージングツールを提供
deb/rpm
pkg/dmg
msi/exe
の全てをカバーしつつ、起動時に渡すパラメータをパッケージング時に
指定可能、API(ToolProvider)が生えててプログラマブルと盛りだくさん
最終的には、 jlink で最適化・最小化された実行イメージを作成し、こ
のパッケージツールでインストーラを作る流れになることを目指してい
る
36
359:Records(Preview)
データクラス。乱暴に言うと構造化されたtuplesのようなもの。
Specificationdraft
{ClassModifier} record TypeIdentifier [TypeParameters]
RecordComponent { , RecordComponent }
  [SuperInterfaces] RecordBody
record NonEmptyString(int x, String s) {}
37
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
データクラスの悩みどころであるコンポーネントの検証や正規化がコン
ストラクタ(canonicalconstructor)として書ける
record NonEmptyString(int x, String s) {
public NonEmptyString {
// Stringコンポーネントをnon emptyに正規化
if ( s == "" ) {
this.s = "JVM is treasure.";
} else {
this.s = s;
}
}
}
39
368:TextBlocks(SecondPreview)
改行(  )と空白( s )を柔軟に制御できるよう2つの新たなエスケープシ
ーケンスが追加される
TextBlock内で末尾に  を付けて改行するとその改行は無視される
s は u0020 (空白)に変換される。前後の余分な空白が削除され
てから変換されるため、結果として s と文字列の間にある空白が
削除されることを防ぐことができる
40
#普通のText Blocks
"""
JJUG
CCC
""" => "JJUG¥nCCC¥n"
#本来は一行で書ききれないめっちゃ長い文章を意図的に改行する時に使う
"""
JJUG 
CCC
""" => "JJUG CCC"
#各行辺りの文字数を制御したい時などに使う
"""
JJUG s
CCC s
""" => "JJUG ¥nCCC ¥n"
41
366:DeprecatetheParallelScavenge+SerialOldGC
Combination
Young領域はParallelでOld領域はSerialでGCを実行するという組み合わ
せが非推奨化された
-XX:+UseParallelGC -XX:-UseParallelOldGC
もちろん、他の組み合わせ、例えば両方ParallelまたはSerialは継続
42
365:ZGConWindows
Linux用であったZGCがWindowsにも移植
43
OpenJDKForks
OpenJDKはリリース後に各団体が長期間メンテナンスを行う予定の
LTS(LongTermSupport、JDK11)のバージョンと、半年間のメンテナ
ンスが行われるそれ以外(non‑LTS、JDK9、10、12)バージョンがある
と、JDK9の時点で言われていたが実際はどうなのか答え合わせをして
いこう
44
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
EclipseOpenJ9
https://www.eclipse.org/openj9/
JDK部分ではなくJVM(JavaVirtualMachine)のオープン実装。JDK部分
にOpenJDKを利用したバイナリがAdoptOpenJDKコミュニティで配布
されている
このためJDK部分のメンテナンスは実質AdoptOpenJDKに準じる。JVM
部分は実装そのものが異なるためバグや脆弱性は独自にEclipseプロジェ
クトで管理されている
46
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
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
RedHatOpenJDK
LinuxDistribution提供のopenjdkパッケージは提供元のパッケージソー
ス、rpmパッケージであればRPMS(SPEC)を確認する
Fedora
RPMSを管理しているgitリポジトリが公開されている
Fedora31(latest)のOpenJDK11のRPMSはここ
OpenJDKのshenandoahプロジェクトのjdk11リポジトリをベース
にicedtea8のtapsetや独自パッチ(Crashバグ修正、暗号ポリシー、
SunJSSE周りの変更(SunPKCS11Provider等)など)を追加している
49
CentOS
Fedora同様RPMSを管理しているgitリポジトリで確認可能
CentOS8(latest)のOpenJDK11
OpenJDKのshenandoahプロジェクトのjdk11リポジトリをベース
(※)にicedtea8のtapsetや独自パッチ(Fedoraとほぼ同じ)を追加
※: update_package.sh によりベースとなるコードのtarballを入手して
いるが、肝心のスクリプトがリポジトリ上にない。同名のファイルが
FedoraのRPMS管理リポジトリにありかつ同一人物がメンテナであるた
め、そこからの推測
50
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
Ubuntu
パッケージングソースがpublicなgitリポジトリで管理されており、
openjdk‑11パッケージはここで管理されている
debian/watchでチェックしているベースとなるupstreamはOpenJDKコ
ミュニティの jdk-updates/jdk11u 。このためメンテナンス期間は
OpenJDKコミュニティに準じる
これに独自パッチ(3.0(quilt))としてSunJSSE(PKCS11)関係のほか、使
用するライブラリ、一部環境のスレッドスタックデフォルト値などを変
更している
52
HeadtowardJava13andJava14
KUBOTAYuji(@sugarlife)
LINECorporation
JJUGCCC2019Fall(2019/Nov/23)

Head toward Java 13 and Java 14 #jjug