Skip to content

Instantly share code, notes, and snippets.

@ykubota
Last active June 24, 2021 00:44
Show Gist options
  • Save ykubota/b37a62de579dc92d02c9483974160c67 to your computer and use it in GitHub Desktop.
Save ykubota/b37a62de579dc92d02c9483974160c67 to your computer and use it in GitHub Desktop.
Java 11による変更点。

Java 11: 利用や動作に影響を与える変更点

Java 10はこちら

なお、本資料に記載しているものの一部は実機確認してないので、お使いのコードを修正する前に動作確認してください :)

はじめに

本資料はCompatibility & Specification Reviewを整理したものです

新しいバージョンがリリースされた時に注目すべきポイントはいくつかあり、よく注目される新機能は JEP として管理されてるのでこれを確認するのがよい。これ以外に JSR で公開されている Specification では新機能レベルではない細かい新規追加 API や削除・非推奨化された API が記載されている

この他に「既存APIの利用や既存アプリの動作に影響を与えるかどうか」という観点があり、ソフトウェア開発コミュニティや企業、特に SIer などの「守り」が重要な団体では最も重要である。これはリリースノートで確認できるが、本資料ではもう少し突っ込んで仕様変更を伴う際に行われるレビューCSR(Compatibility & Specification Review)Issue Trackerソースコード+構成管理情報から調査し、ユーザが影響を受ける可能性がある変更内容を整理した

API

既存アプリケーションのAPIへの影響、つまりソースコードレベルの修正が必要となり得る変更

Add

  • 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) が出力される。判明後アップデート予定
  • JDK-8198512: Add compiler support for local-variable syntax for lambda parameters
    • JEP 323によりvarがlambdaにも使えるようになった
    • APIの追加というよりはコンパイラのparserが変わる非互換性。ユーザ的には影響はなく、コードの記述方法が単純に増えるのでここに記載した

Remove

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.SelectorAPIは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の状態にかかわらず対応フレームがポップされると常にクリアされるようになった

Deprecate

Tool

ツール利用に影響があり得る変更

Remove

Change

  • 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としてカウントされていたので、一貫性を保つように修正が行われた
    • どちらかというと動作の変更だが、ユーザ的に影響があるのはjstatjcmd PerfCounter.printでのCGC値が変わることであり、ツールの非互換性の側面が大きい

Option

オプション関係の変更。動作の非互換性が生じる可能性がある

Add

  • JDK-8198756: Lazy allocation of compiler threads
    • -XX:+UseDynamicNumberOfCompilerThreadsが追加された。デフォルトで有効
    • これまでは富豪的にスレッドを作ってコンパイルしていたため過分にメモリ消費などリソース利用が非効率的であったが、適切にスレッドを管理することで解消された

Remove

Deprecate

  • JDK-8199777: Deprecate -XX:+AggressiveOpts
    • -XX:+AggressiveOptsオプションが非推奨化。将来的に削除される
    • 元々は特定ベンチでC2コンパイラを実験的に最適化していたもので、一般ユーザがわざわざ利用することはない
    • 内部挙動的には-XX:AutoBoxCacheMax=20000,-XX:BiasedLockingStartupDelay=50が設定されたのと同じ挙動となる。必要であればこれを設定すれば再現可能

Change

  • 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を明示的に付ける必要がある

Behavior

セキュリティ以外のGCなどの動作関係の変更

Add

Change

Security

セキュリティ関係の変更

Others

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment