- Author: KUBOTA Yuji
- twitter: https://twitter.com/sugarlife
- email: kubota.yuji [at] gmail.com
なお、本資料に記載しているものの一部は実機確認してないので、お使いのコードを修正する前に動作確認してください :)
本資料はCompatibility & Specification Reviewを整理したものです
新しいバージョンがリリースされた時に注目すべきポイントはいくつかあり、よく注目される新機能は JEP として管理されてるのでこれを確認するのがよい。これ以外に JSR で公開されている Specification では新機能レベルではない細かい新規追加 API や削除・非推奨化された API が記載されている
この他に「既存APIの利用や既存アプリの動作に影響を与えるかどうか」という観点があり、ソフトウェア開発コミュニティや企業、特に SIer などの「守り」が重要な団体では最も重要である。これはリリースノートで確認できるが、本資料ではもう少し突っ込んで仕様変更を伴う際に行われるレビューCSR(Compatibility & Specification Review)をIssue Trackerとソースコード+構成管理情報から調査し、ユーザが影響を受ける可能性がある変更内容を整理した
既存アプリケーションのAPIへの影響、つまりソースコードレベルの修正が必要となり得る変更
- JDK-8203394: Implementation of JEP 331: Low-Overhead Heap Profiling
- JEP 331: Low-Overhead Heap ProfilingによりJavaヒープアロケート状況をサンプリングするJVMTI APIが追加された。ツールではないので注意
- 純粋な追加なのでソースレベルの影響はないのだが、使うとパフォーマンスに少なからず影響が発生する。使わなければ当然その影響もない
- Flight Recorderがオープン化される前から取り組まれていたのだが、結果的に同時に入った可哀そうな変更。殆どのユーザはFlight Recorderを使ったほうが性能面でも良い
- JDK-8060192: Add default method <A> A[] Collection.toArray(IntFunction<A[]> generator)
java.util.Collection
インターフェースに新しいデフォルトメソッドtoArray(IntFunction)
が追加された。これは既存メソッドtoArray(T[])
のオーバーロードである- インターフェースの変更なので影響(ソースの非互換性)が発生する。バイナリの非互換性は発生しない
- 例えば
list.toArray(null)
のようなコードは、今まではtoArray(T[])
メソッドと解決していたのが、toArray(IntFunction)
とも一致してしまうため解決ができずコンパイル時にエラーが発生する - 以前のバージョンでコンパイル済みの場合は
toArray(T[])
にリンクされてるので問題は生じない=バイナリの非互換性は発生しない
- 例えば
- JDK-8202088: Japanese new era implementation
- 平成の次の元号が出力するための前準備
java.time.chrono.JapaneseEra.of(3).getDisplayName(java.time.format.TextStyle.FULL, Locale.JAPAN)
==> "元号"- 今は元号が確定していないので数字(3)で指定が必要
- 今は"元号" (Locale.JAPAN) や "NewEra" (Locale.US) が出力される。判明後アップデート予定
- しかし政府が1ヵ月しか余裕を持たせなかったのでほぼ確実に間に合わない
- JDK-8198512: Add compiler support for local-variable syntax for lambda parameters
- JEP 323により
var
がlambdaにも使えるようになった - APIの追加というよりはコンパイラのparserが変わる非互換性。ユーザ的には影響はなく、コードの記述方法が単純に増えるのでここに記載した
- JEP 323により
- JDK-8190378: Remove the Java EE and CORBA modules
- JJUG CCC 2018 Fallのスライド参照
- JDK-8204243: remove Thread.destroy() and Thread.stop(Throwable)
Thread.destroy()
とThread.stop(Throwable)
がついに削除されたThread.stop()
は残されており影響はない
- JDK-8204187: Remove proprietary JPEG code from javax.imageio
- Oracle JDKのJPEGライブラリ独自拡張が削除された。(使ってる人は少ないと思うが詳細はリンク先を確認)
- JDK-8193033: remove terminally deprecated sun.misc.Unsafe.defineClass
- JDK Internal APIの
sun.misc.Unsafe.defineClass
が削除された java.lang.invoke.MethodHandles.Lookup.defineClass
が代替API
- JDK Internal APIの
- JDK-8200149: The "com.sun.awt.AWTUtilities" class can be dropped
com.sun.awt.AWTUtilities
クラスが削除された- Java 10で非推奨化されてそのまま削除されたケース。ただし、JDK内部用途であったのと、ウィンドウを透明化したい場合は
javax.swing.JFrame
などを用いて実行することがJava 7から可能(詳細)であるため影響はない
- JDK-7183985: (ann) Class.getAnnotation() throws an ArrayStoreException when the annotation class not present
- クラスパスに指定のアノテーションクラスがなかった場合、
Class.getAnnotation()
はArrayStoreException
を投げていたが、正しくTypeNotPresentException
を投げるように修正された - JDK 6時代からのバグ
- クラスパスに指定のアノテーションクラスがなかった場合、
- JDK-8197564: HTTP Client implementation
- JEP 321: HTTP Client (Standard)により JDK 9で incubated として導入されていた HTTP Client API が更新&標準APIに昇格した
- 詳細はAPI javadoc (
java.net.http
)で確認ができる。量が多いのでここでは触れない - ユーザ的には"Add"だがincubatedが外れてモジュールの名前が変わったので"Change"
- JDK-8201793: (ref) Reference object should not support cloning
java.lang.ref.Reference::clone
メソッドは廃止され常にCloneNotSupportedException
を投げるようになった- コンストラクタを読んで新たなReferenceオブジェクトを作ってクローンしましょう
- JDK-8194554: filterArguments runs multiple filters in the wrong order
java.lang.invoke.MethodHandles.filterArguments
は引数として渡されたフィルターを左から順に呼び出す仕様であったが、実際は右から順に呼び出していたバグを修正した- 二つ以上のフィルタを渡していた場合、順番が変わるので動作の非互換性が発生し得る
- JDK-8201315: (se) Allow SelectableChannel.register to be invoked while selection operation is in progress
java.nio.channels.SelectableChannel.register
がスレッドセーフになった- 実装には
SocketChannel
,ServerSocketChannel
クラス等がある
- 実装には
- これに伴い
java.nio.channels.Selector
のキーセットの選択操作(selection-op)は同期するように指定されたSelectorProvider
を提供しているライブラリはこの変更を受けて修正をする必要がある
- JDK-8200458: (se) Readiness information previously recorded in the ready set not preserved
java.nio.channels.Selector
APIはSelectionKeyが選択したキーセットに既にあった場合、readiness informationをオーバーライドしてしまい正しく以前の情報が保持されていなかった問題を修正。一部のユースケースで動作の非互換が発生する
- JDK-8198753: (dc) DatagramChannel throws unspecified exceptions
java.nio.channels.DatagramChannel.send(ByteBuffer,SocketAddress)
を呼び出した際、DatagramChannel
が接続しているアドレスとメソッド引数のアドレスが異なっている場合、これまではIllegalArgumentException
を投げていたが、Java 11からはjava.nio.channels.AlreadyConnectedException
が投げるようになった
- JDK-8197533: Split java.sql to create module java.transaction.xa
javax.transaction.xa
パッケージがJava SEに残されることになり、java.transaction.xa
モジュール(javaxからjavaになった)が新しく作られた- これに伴い
java.sql
に含まれていたjavax.transaction.xa
が削除された - モジュール化されてないライブラリには影響がない。モジュール化していて、
javax.transaction.xa
を使っている場合はmodule-info.java
の更新が必要
- JDK-8198803: URLClassLoader does not specify behavior when URL array contains null
java.net.URLClassLoader
のコンストラクタに渡されたURLにnull要素が含まれていた場合、NullPointerException
を投げるようになった
- JDK-8198562: (ch) Separate blocking and non-blocking code paths (part 1)
- part2( JDK-8198754)含め関連パッチが4つもある大きめの変更
java.nio.channels.SocketChannel
,java.nio.channels.ServerSocketChannel
,java.nio.channels.DatagramChannel
,java.nio.channels.Pipe.SourceChannel
,java.nio.channels.Pipe.SinkChannel
がブロッキングとノンブロッキングI/Oのコードパスが分離されるようにリファクタリングされ、パフォーマンスやI/O操作の信頼性が向上した。ただし、以下の動作の非互換性が発生するSelector
で登録されていたSocketChannel
を閉じた際、このChannelが登録されている全てのSelectorからflushされるまで接続を閉じる処理が一貫して遅くなる- ノンブロッキングなChannel上でI/O操作を呼び出すと割り込みステータスが設定されChannelが閉じられなくなった
configureBlocking(false)
メソッドを呼び出すと、未処理のブロッキングI/O操作が完了するまで待機する(ブロックされる)ようになった
- JDK-8187289: NotifyFramePop request is not cleared if JVMTI_EVENT_FRAME_POP is disabled
- JVMTIの変更。
NotifyFramePop(jvmtiEnv*, jthread, jint)
はJVMTI_EVENT_FRAME_POP
が有効時のみクリアされたが、Java 11からはJVMTI_EVENT_FRAME_POP
の状態にかかわらず対応フレームがポップされると常にクリアされるようになった
- JVMTIの変更。
- JDK-8072996: Deprecate stream-based GSSContext methods
- RFC 8353から削除された
org.ietf.jgss.GSSContext
の一部メソッドが非推奨化
- RFC 8353から削除された
- JDK-8204492: Add deprecation annotation to Nashorn APIs and warning to nashorn, jjs
- JEP 335: Deprecate the Nashorn JavaScript EngineによりNashornとjjsツールが非推奨化。将来的に削除される
-Dnashorn.args=--no-deprecation-warning
オプションで警告非表示が可能
- JDK-8199871: Deprecate pack200 and unpack200 tools
java.util.jar
のPack200 APIが非推奨化。将来的に削除されるpack200
,unpack200
ツールが非推奨化。 JDK 11では同梱されるが更新はされない
ツール利用に影響があり得る変更
- JDK-8200146: Remove the appletviewer launcher
- appletviewer launcherが削除された
- AppletやJava Web Startは削除されると発表された
- JDK-8071367: Remove SNMP agent
- SNMP agentが削除された
- Oracle JDKに導入されてから(Oracleに)あまり問合せやフィードバックがなかったのもあり、Java 10で非推奨化、Java 11で削除という流れになった
- JDK-8206211: Drop JVM-MANAGEMENT-MIB.mib from Java SE
- SNMP Agentの削除に伴いMIBファイルが削除された
- JDK-8191438: jarsigner should print when a timestamp will expire
- 署名ツールである
jarsigner
は有効期限付きJARファイルが期限切れ、ないしは期限切れまで1年以内の場合にエラーや警告を出力するようになった - 今まで出してなかったのか…
- 署名ツールである
- JDK-8153333: STW phases at Concurrent GC should count in PerfCounter
- G1 GCのRemarkとCleanupフェーズのSTW(Stop-The-World、アプリの一時停止)がCGCとしてカウントされていなかったのを修正
- CMS GCはSTWが発生するフェーズはCGCとしてカウントされていたので、一貫性を保つように修正が行われた
- どちらかというと動作の変更だが、ユーザ的に影響があるのは
jstat
やjcmd PerfCounter.print
でのCGC値が変わることであり、ツールの非互換性の側面が大きい
オプション関係の変更。動作の非互換性が生じる可能性がある
- JDK-8198756: Lazy allocation of compiler threads
-XX:+UseDynamicNumberOfCompilerThreads
が追加された。デフォルトで有効- これまでは富豪的にスレッドを作ってコンパイルしていたため過分にメモリ消費などリソース利用が非効率的であったが、適切にスレッドを管理することで解消された
- JDK-8202331: Obsolete support for commercial features
- 商用機能オープン化に伴い
-XX:+UnlockCommercialFeatures
と-XX:+LogCommercialFeatures
が廃止 jcmd
のコマンドVM.unlock_commercial_features
とVM.check_commercial_features
も廃止
- 商用機能オープン化に伴い
- JDK-8198385: Remove property sun.locale.formatasdefault
- Java 7で導入された
sun.locale.formatasdefault
プロパティが削除された - 既に
file.encoding
プロパティなどでより簡易に設定可能なため無用の長物だった
- Java 7で導入された
- JDK-8196535: Remove support for pre-Java 6 non-JVM-wide file locking
sun.nio.ch.disableSystemWideOverlappingFileLockCheck
プロパティ削除- JDK 6で互換性のために導入されたファイルのロック制御に関わるプロパティ。もはやJDK 6よりも古い動作は不要となり削除された
- JDK-8199777: Deprecate -XX:+AggressiveOpts
-XX:+AggressiveOpts
オプションが非推奨化。将来的に削除される- 元々は特定ベンチでC2コンパイラを実験的に最適化していたもので、一般ユーザがわざわざ利用することはない
- 内部挙動的には
-XX:AutoBoxCacheMax=20000
,-XX:BiasedLockingStartupDelay=50
が設定されたのと同じ挙動となる。必要であればこれを設定すれば再現可能
- JDK-8066709: Make some JDK system properties read only
- 以下のプロパティは起動時にキャッシュされ変更不可となった
java.home
,user.home
,user.dir
,user.name
System::setProperty
で変更しても標準API(java.base
)の動作は影響を受けない
- JDK-8198510: Enable UseDynamicNumberOfGCThreads by default
-XX:+UseDynamicNumberOfGCThreads
がデフォルトで有効となった- Javaヒープの最大サイズに基づいてGCスレッドを決定する設定。ヒープサイズが小さい場合はスレッド数が少なくなるため、起動時間やリソース使用量が効率化される反面、性能が低下する場合もある
- JDK-8194937: Inconsistent behavior of --validate-modules when combined with -m and other options
--validatate-modules
がより多くのケースで正常に動作するように改良された- このオプションはモジュールの競合や重複、不正な記述子など様々なモジュールの問題を特定するために便利なオプションだが、問題の内容に依ってはJVM初期化処理の失敗により検証結果を出力する前に終了してしまうという鶏卵問題に陥ることケースがあった
- 強制終了前に検証結果を出力されるように改善が行われた。このため、ユーザへの影響はないが動作の非互換性が生じる
- JDK-8188105: Make -Xshare:auto the default for server VM
- これまでserver VM利用時はCDSが無効化(
-Xshare:off
)になっていたが、デフォルトで可能なら有効にする(-Xshare:auto
)ようになった - 今までCDSが有効だと
RewriteBytecodes
が無効になりC2コンパイラ性能が劣化する問題があった。これがJDK-8074345で解決されたのでデフォルトで有効にするという流れ - 無効にしたい場合は
-Xshare:off
を明示的に付ける必要がある
- これまでserver VM利用時はCDSが無効化(
セキュリティ以外のGCなどの動作関係の変更
- JDK-8209963: source file mode for JVM should provide a hook to locate the source file
- JEP 330: Launch Single-File Source-Code Programsにより、スクリプトのように単体Javaファイルを直接実行できるようになった
- 詳細はこちらのスライドで解説してる
- JDK-8204210: Implementation: JEP 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)
- JEP 333により巨大ヒープ向け低レイテンシGCが試験的に追加された
- JDK-8204180: Implementation: JEP 318: Epsilon, A No-Op Garbage Collector
- JEP 318により「何もしない(no-op)」GCが試験的に追加された
- JDK-8197532: Re-examine policy for the default set of modules when compiling or running code on the class path
- ルートモジュールのデフォルトセットが変更された
- 具体的には
java.se
が外され解決できなくなった
- JDK-8193302: Javac AssertionError: typeSig ERROR on usage of @Generated
javac
で-source >=9
や-release >=9
を指定してコンパイルする際、コンパイル対象のクラスが所属しているモジュールから不可視なパッケージをimportしている場合は失敗するようになった
- JDK-8010319: Implementation of JEP 181: Nest-Based Access Control
- JEP 181: Nest-Based Access Controlが追加された
- 端的に言うとネストする側とされる側のバイトコード出力が整理された
- ソースの非互換性は生じないが、ASM bytecode manipulationやjavap classfile inspectionツールなどはほぼ確実に影響を受ける
- JDK-8202537: Update locale data to Unicode CLDR v33
- CLDRがVersion 33にアップデート
- ロケールデータはJava 9からデフォルトでCLDRが優先されている
- JDK-8191410: Unicode 10.0.0 support
- JEP 327: Unicode 10をサポート。新たな絵文字も使えるように
- JDK-8207032: Compilation succeeds without checking readability when --add-exports used
javac
で--add-exports
オプションを用いると自動的にターゲットモジュールからエクスポートモジュールが読み込み可能になっていたのが修正された。今後は適切に--add-reads
オプションを利用する必要がある- 読込や公開範囲を制御するためのモジュール化の筈なのに、自動的に公開しちゃってたのでちゃんと制御させますよという修正
- JDK-8203664: JFR start failure after AppCDS archive created with JFR StartFlightRecording
- CDS(Class Data Sharing)のダンプ中はFlight Recorderが無効化されるようになった
- JDK-8187577: JVM crash during gc doing concurrent marking
- 並行マーキング時に到達不可能とみなされていたクラスが、スレッドローカルなJNIHandlesに格納されていて後から参照されてクラッシュするケースがあった
- このため、
ClassLoaderData/SystemDictionary
からフェッチされたクラスが復活した場合はG1のSTABに通知されるように修正が行われた - Java 8にバックポート済み
- JDK-8205043: Make parallel reference processing default for G1
- GCスレッドが1より多い場合、デフォルトで
ParallelRefProcEnabled
が有効になり、参照処理が並列化される
- GCスレッドが1より多い場合、デフォルトで
- JDK-8205064: Fail immediately if an unavailable GC is selected
- これまでは使用できないGC (例:minimalなJVMビルドではG1は使えない)を指定した場合は警告メッセージを出しつつ別のGCを利用して起動していたが、Java 11からは直ちに終了するように修正された
- モジュール化やProject PortlaによりGCを限定したビルドが作成可能になったため、このようなケースが発生していた
- JDK-8198649: Switch AWT/Swing's default GTK version to 3
- Java 9からサポートしたGTK3をデフォルトにした (見た目が多少変わる)
- 引き続きGTK2.2を使いたい場合は
-Djdk.gtk.version=2.2
を設定する
- JDK-8198794: Hotspot crash on Cassandra 3.11.1 startup with libnuma 2.0.3
- 古いlibnuma(<=2.0.9)でNUMAを使っていた(
-XX:+UseNUMA
)場合、クラッシュする問題がありその修正が行われた。JVM内処理の変更が入ったがユーザ的には気にしなくて大丈夫 - Java 8にもバックポートが行われている。古いlibnumaを使う場合はアップデートが必要
- 古いlibnuma(<=2.0.9)でNUMAを使っていた(
- JDK-8187950: javax.lang.model APIs throws CompletionFailure or a subtype of CompletionFailure.
- 型が見つからない(missing type)エラーや
javac
内部例外、CompletionFailure
はAPIクライアントにスローされなくなった
- 型が見つからない(missing type)エラーや
- JDK-8194812: Extend class-data sharing to support the module path
- CDS利用時に module path を設定していた場合は無視して警告を表示していたが、Java 11からサポートされた。ただし以下のような制約がある
- モジュール化済みJARファイルのみ対応。automatic moduleは未対応
--upgrade-module-path
,--patch-module
,--limit-modules
は未対応。CDS出力時(-Xshare:dump
)に設定すると即時終了し、 CDS実行時(-Xshare:{on,auto}
)に設定するとCDSが無効化される
- JDK-8190324: ThreadPoolExecutor should not specify a dependency on finalization
Object.finalize
の非推奨化に伴い、java.util.concurrent.ThreadPoolExecutor
のクリーンアップ処理が変更され、スレッドプールをシャットダウンするfinalize
メソッドは何もしなくなったfinalize
メソッドを実行しているだけならば影響はないが、スレッドプールがシャットダウンされている前提で処理を続けて行っている場合は、その保証がなくなったため動作の非互換性が生じる可能性がある
セキュリティ関係の変更
- Remove cacerts.internal from Oracle JDK
- ルート証明書(AOLとSwisscom)が削除された
- JDK-8191844: Remove SECOM root (secomevrootca1)
- 一部のルート証明書(SECOM)が削除された
- JDK-8189949: Remove Baltimore Cybertrust Code Signing CA
- 一部のルート証明書(Baltimore Cybertrust Code Signing)が削除された
- JDK-8191031: Remove several Symantec Root CAs
- 一部のルート証明書(Symantec)が削除された
- JDK-8209506: Add Google Trust Services GlobalSign root certificates
- 一部のルート証明書(Google Trust Services GlobalSign)が追加された
- JDK-8199779: Add T-Systems, GlobalSign and Starfield services root certificates
- 一部のルート証明書(T-System、Amazon (Starfield Services)、GlobalSign)が追加された
- JDK-8195774: Add Entrust root certificates
- 一部のルート証明書(Entrust)が追加された
- JDK-8196141: Add GoDaddy root certificates
- 一部のルート証明書(GoDaddy)が追加された
- JDK-8209965: The "supported_groups" extension in ServerHellos
- セキュリティ修正。 ServerHello ハンドシェイクメッセージにsupported_groups拡張(RFC7919)は存在するべきではないが、そのチェックを行っていなかったのを修正
- JDK-8205445: Add RSASSA-PSS Signature support to SunMSCAPI
- SunMSCAPIプロバイダがRSASSA-PSS署名アルゴリズムをサポート
- JDK-8198925: ChaCha20 and ChaCha20-Poly1305 Cipher Implementations
- JEP 329: ChaCha20 and Poly1305 Cryptographic AlgorithmsにてRFC 7539のChaCha20とChaCha20-Poly1305暗号方式が追加された
- JDK-8171277: Elliptic Curves for Security in Crypto
- JEP 324: Key Agreement with Curve25519 and Curve448にてRFC 7748の公開鍵暗号Curve25519とCurve448が追加された
- JDK-7007966: Add Brainpool ECC support (RFC 5639)
- SunECプロバイダはRFC5639の4つのBrainpool楕円曲線暗号をサポートするようになった
- JDK 7時代に提案されていたものがようやく入った。なおSunJSSEは未対応
- JDK-8196584: TLS 1.3 Implementation
- JEP 332: Transport Layer Security (TLS) 1.3によりRFC 8446のTLS 1.3がサポートされ、新たなオプションがいくつか追加さた。詳細はJava Secure Socket Extension(JSSE) Doc参照
- TLS 1.3は1.2以前とは互換性が一部損なわれているため、利用する場合は動作の非互換性が生じる
- JDK-8208526: TLS 1.3 half-close and synchronization issues
- duplex-closeを強制する
jdk.tls.acknowledgeCloseNotify
プロパティが追加された - TLS 1.2以前はduplex-close policyだがTLS 1.3はharf-close policyである。この差異をソースコードを変更することなく対応するために用意された
- duplex-closeを強制する
- JDK-8177334: Update xmldsig implementation to Apache Santuario 2.1.1
- XMLデジタル署名の実装がApache Santuario 1.5.4から2.1.1に更新された
- JDK-8201627: Kerberos sequence number issues
- Kerberos 5初期処理にて相互認証が要求されなかった場合に初期シーケンス番号をネゴシエートする仕組みがなかったので追加された
sun.security.krb5.acceptor.sequence.number.nonmutual
で設定が可能
- JDK-8200152: KerberosString should use UTF-8 by default
KerberosString
のデフォルトエンコードがASCIIからUTF-8に変更された-Dsun.security.krb5.msinterop.kstring=false
を指定することで従来通りASCIIが利用可能
- JDK-8014628: Support AES Encryption with HMAC-SHA2 for Kerberos 5 defined in RFC 8009
- Kerberos 5にRFC 8009のHMAC-SHA2 AES暗号がサポートされた。これはデフォルトで利用される
- 変更したい場合は
krb5.conf
のdefault_tkt_enctypes
とdefault_tgs_enctypes
にて指定できる