- Author: KUBOTA Yuji
- twitter: https://twitter.com/sugarlife
- email: kubota.yuji [at] gmail.com
なお、本資料に記載しているものの一部は実機確認してないので、お使いのコードを修正する前に動作確認してください :)
本資料はCompatibility & Specification Reviewを整理したものです
新しいバージョンがリリースされた時に注目すべきポイントはいくつか考えられる。よく注目される新機能は JEP として管理されるのでこれを確認するのがよい。これ以外に JSR で公開されている Specification は主に新機能レベルではない細かい新規追加 API や削除・非推奨化された API が記載されている。前者については色々なメディアや記事で取り上げられ、後者については有名なものでSimon Ritterや桜庭さんがblogで取り上げている。
これらでは含まれていないポイントとして、APIの利用や動作に影響を与える変更点がある。企業、特に SIer などの「守り」が重要な企業では最も重要な項目である。これはいわゆる互換性を破壊するものであり、本資料はこれを列挙・整理している。講演ではこの中からピックアップして説明する。
Java 9までは機能ドリブンで機能の開発が間に合わなかった場合はリリースが延期されることになった。Java 10 からはタイムドリブンで締切に間に合った機能が搭載されるため、何かしらの機能が間に合わないからリリース延期ということは起こらない(はず)。本資料に挙げたものはJava 10に搭載されたものだが、一部はバックポートされてJava 9以前でも利用できる物がある。つまり非互換性が前バージョンに波及する事もある。ただし、LTS 以外は半年しか生存しないはずなので基本的には気にしなくて良い(はず)
Dockerなどのコンテナ上で Java を動作させた時に問題が発生していたため Java 8 から少しずつ改善が行われてきた。この問題とは、コンテナ等のゲスト環境の情報ではなくホストのOS情報を元にCPU数やメモリ量を算出して初期設定が行われていたため、過分にGCスレッドやJavaヒープサイズを割当てていたというもの。Java 8やJava 9でも改善が行われてきたが完全な対応には至って居らず、動作の変更も伴うためJava 10リリースのタイミングで最終的な改善取組が行われた。(バグや要望があれば引き続き改善は行われるはず)
これは本来はOptionおよびBehaviorの項目に入れるべきだが解りやすいように別にしている
- JDK-8146115: Improve docker container detection and resource configuration usage
- コンテナを認識せずホストのCPU数とメモリを基に設定や動作が行われていた問題を修正
- -XX:+UseContainerSupport (デフォルト有効) が追加された。オフにすることでこの動作の変更を無効にすることができる(≒JDK 9以前と同じ動作にすることができる)
-Xlog:os+container=trace
でコンテナ情報のロギングが可能になった
- CPU数をcpu sets, cpu shares, cpu quotasを基に設定するようになった
- -XX:ActiveProcessorCount= で上書可
- 利用可能メモリサイズをcgroup filesystemの memory_limit を基に設定するようになった
- コンテナを認識せずホストのCPU数とメモリを基に設定や動作が行われていた問題を修正
- JDK-8186248: Allow more flexibility in selecting Heap % of available RAM
- ヒープに使用するシステムメモリ量を柔軟に設定することが可能になった。
- -XX:{Initial,Max,Min}RAMPercentage
- 既存のオプションに -XX:{Min,Max}RAMFraction と言うものがあるが、これは割合値を指定するものであり直感的ではなかった。(例えば、8を指定すると1/8となる)
- JDK-8179498: attach in linux should be relative to /proc/pid/root and namespace aware
- ホストからコンテナ上のプロセスにアタッチできるように改善された。
- アタッチメカニズムに変更が入ったので動作の非互換性
- JDK-8140281: (opt) add no-arg orElseThrow() as preferred alternative to get()
java.util.Optional::orElseThrow()
- 動作や利用に影響はないが、
Optional::get()
から置き換えが推奨されている。get()
はそのうち非推奨になるかも(※推測です)
- JDK-8177290: add copy factory methods for unmodifiable List, Set, Map
java.util.{List,Set,Map}::copyOf
- 引数のコレクションが変更可能な場合はコピーして変更不可能(unmodifiable)なコレクションを返し、引数が変更不可能な場合はリファレンスを返す(shallow copy)メソッドが追加された
- 関連して JDK-8184690: add Collectors for collecting into unmodifiable List, Set, and Map により、
java.util.stream.Collectors
クラスに、変更不可能なコレクションを返すためのメソッドtoUnmodifiableList
、toUnmodifiableSet
、toUnmodifiableMap
メソッドが追加されました - ヒープ汚染(heap pollution)を防ぐために、変更不可能かどうかの確認メソッドや変更不可能なコレクションを作成するメソッドが求められていました。これらのメソッドはそれらの要望の助けになるため、自作していた場合は乗り換えを行いましょう
- パッチ: http://hg.openjdk.java.net/jdk/jdk/rev/6ee80cd217e0
- JDK-8185683: Inaccessible and unused classes can be removed from java.desktop module
- アクセス不可or使われていなかった
java.desktop
モジュールのJDK内部Swing LookAndFeels インスタンスを生成するAPIを削除。代替APIあり。 javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
javax.swing.UIManager.setLookAndFeel("apple.laf.AquaLookAndFeel");
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- 内部APIである
com.apple.eawt.ApplicationListener
、com.sun.java.swing.Painter
も一緒に消えてる。後者はjavax.swing.Painter<T>
ではないことに注意
- アクセス不可or使われていなかった
- JDK-8159544: Remove deprecated classes in com.sun.security.auth.**
- 非推奨且つ
forRemoval=true
マーク済みAPIを削除 com.sun.security.auth.PolicyFile
com.sun.security.auth.SolarisNumericGroupPrincipal
com.sun.security.auth.SolarisNumericUserPrincipal
com.sun.security.auth.SolarisPrincipal
com.sun.security.auth.X500Principal
com.sun.security.auth.module.SolarisLoginModule
com.sun.security.auth.module.SolarisSystem
- 非推奨且つ
- JDK-8187637: Remove deprecated VP6/FXM/FLV code from JavaFX
- Java 9で非推奨となっていたVPFビデオエンコード形式とFXM/FLVコンテナのAPIがJavaFX Mediaから削除されました。(JDK-8134330: Deprecate VP6/FXM/FLV support in JavaFX Media)
- MP4コンテナやHTTPライブストリーミングでH.264/AVC1を使用しましょう。
- JDK-8187149: Remove deprecated HostServices::getWebContext method
- アプレットの非推奨化と関連してJDK 9で非推奨かつ
forRemoval=true
マーク済み(JDK-8156963: Deprecate HostServices.getWebContext method)のAPI(メソッド)を削除、代替なし。これによりJavaFXアプレットのWebページと通信が出来なくなった。 javafx.appliction.HostServices::getWebContext
- アプレットの非推奨化と関連してJDK 9で非推奨かつ
- JDK-8186535: Remove deprecated pre-1.2 SecurityManager methods and fields
- JDK 1.2 以前?から非推奨であり
forRemoval=true
マーク済みのjava.lang.SecurityManager
の以下のフィールドとメソッドが削除された。inCheck
fieldgetInCheck
methodclassDepth
methodclassLoaderDepth
methodcurrentClassLoader
methodcurrentLoadedClass
methodinClass
methodinClassLoader
method -SecurityManager#checkPermission
に置き換えましょう
- JDK 1.2 以前?から非推奨であり
- JDK-8177681: Remove terminally deprecated methods Runtime.getLocalized{Input,Output}Stream
- JDK 1.1 から非推奨な国際化メカニズムの一部であったメソッドを削除。
java.lang.Runtime::getLocalizedInputStream
java.lang.Runtime::getLocalizedOutputStream
- JDK-8181149: Fix lint warnings in JAXP repo
java.xml
APIの以下のraw typeを宣言していたメソッドが型パラメータを追加しましたjavax.xml.namespace.NamespaceContext
Iterator<String> getPrefixes(String namespaceURI);
javax.xml.xpath.XPathFunction
public Object evaluate(List<?> args)
org.xml.sax.helpers.NamespaceSupport
public Enumeration<String> getPrefixes()
public Enumeration<String> getPrefixes(String uri)
public Enumeration<String> getDeclaredPrefixes()
- JDK-8024352: MBeanOperationInfo accepts any int value as "impact"
javax.management.MBeanOperationInfo.MBeanOperationInfo
コンストラクタのimpact
パラメータにINFO
、ACTION
、ACTION_INFO
、UNKNOWN
のいずれかでない int 値を渡した場合、IllegalArgumentException
がスローされるようになりました - JavaDocに上記のパラメータを渡すべしと書かれているのにも関わらず今まではスルーパスだった
- JDK-8080225: FileInput/OutputStream/FileChannel cleanup should be improved
java.io.FileInputStream
およびjava.io.FileOutputStream
は、ファイナライズを使用して最終的なクローズを実行していた。非推奨な方法かつGCへの影響もあるため、これをが修正された
- JDK-8187639: TrayIcon is not properly supported on macOS in multi-screen environment
java.awt.TrayIcon.displayMessage()
on macOSNSUserNotification
APIを利用するように再実装され、カスタムウィンドウではなく標準の通知センターによりメッセージが表示されるようになりました
- JDK-8159535: Mark deprecated javax.security.auth.Policy API with forRemoval=true
forRemoval=true
となった。1.4から非推奨でjava.security.Policy
に置き換えられていた。javax.security.auth.Policy
- JDK-8175091: Mark the deprecated java.security.{Certificate,Identity,IdentityScope,Signer} APIs with forRemoval=true
forRemoval=true
となった。java.security.{Certificate, Identity, IdentityScope, Signer}
- JDK-8175094: Mark the deprecated java.security.acl APIs with forRemoval=true
forRemoval=true
となった。java.security.acl
パッケージに含まれるAPI全部
- JDK-8183519: XMLInputFactory.newFactory() is marked as deprecated
javax.xml.stream.XMLInputFactory::newFactory()
が非推奨では なくなった- Java 9で非推奨の警告を受けて
javax.xml.stream.XMLInputFactory::newInstance()
を利用するようにしたアプリケーションには影響は無し。このメソッドはそのまま残される。
- JDK-8173425: Javadoc needs a new tag to specify the summary.
- Javadoc に
@summary
が追加され明示的にサマリを指定可能になった。動作の非互換性はありません(が、乗り換え推奨っぽい)
- Javadoc に
- JDK-8157000: Do not generate javadoc for overridden method with no spec change
javadoc
に--override-methods (detail|summary)
オプションが追加された- オーバーライドされたメソッドを詳細または要約セクションでドキュメント化する。
@inherited
はプライマリメソッドの要約セッションにリストされ読みづらくなっていたことへの解決策
- JDK-8185371: Support for multiple stylesheets in javadoc
javadoc
が複数スタイルシート利用をサポートしました- 新しく追加された
--add-stylesheet <file>
オプションで指定する --main-stylesheet <file>
-stylesheetfile <file>
オプションで指定する--main-stylesheet
オプションは新しく追加された
- JDK-8185985: Html files in doc-files directories should be wrapped with standard header and footer
javadoc
ツール(の標準doclet)にて各ページにおけるヘッダー(-top
)とフッター(-bottom
)が設定できるようになりました - サンプル:https://bugs.openjdk.java.net/secure/attachment/72711/javadoc.png
- JDK-8148371: Remove policytool
policytool
- JDK-8182758: JEP 313: Remove the Native-Header Generation Tool (javah)
javah
- Java 8から
javac -h
で代替可能 (JDK-7150368: javac should include basic ability to generate native headers)
- JDK-8177511: Remove the old standard doclet
- JDK 6、JDK 7およびJDK 8時代の標準ドックレットが削除された。javadoc API(
com.sun.javadoc
)は推奨されないが使用可能。
- JDK 6、JDK 7およびJDK 8時代の標準ドックレットが削除された。javadoc API(
- JDK-8180019: javadoc should treat failure to access URL as an error, not a warning.
javadoc
ツールは-link
または-linkoffline
オプションで渡されたURLにアクセスできなかった場合、今まで警告を出しつつ実行されていたものがエラーとなるように変更されました
- JDK-8167638: javac can improve the error message issued when IllegalAccessError is produced
javac
でjava.lang.IllegalAccessError
発生時のエラーメッセージがユーザフレンドリになりました- mavenなどで複数クラスローダを利用するケースなどで発生する場合がありました
- JDK-8044853: Attr synthesizes nullcheck tree nodes
- Abstract Syntax Tree(AST)の処理において、New Class AST ノードで Enclosing expression (inner expressionを持つ式) に対して処理を行った際に null を返していたものが適切な式を返すようになった
javac
の動作変更。テストコード
- JDK-8179018: Remove obsoleted one X options from JDK 10
- 廃止済みXオプションを削除
- -Xoss
- -Xsqnopause
- -Xoptimize
- -Xboundthreads
- -Xusealtsigs
- JDK-8173715: Remove FlatProfiler
- Java 9で非推奨となった FlatProfiler が削除された
- -Xprof (警告が表示される、動作はしない)
- JDK-8184286: print_tracing_info() does not use Unified Logging for output
- Unified JVM Loggingの統合漏れ。
-Xlog:gc+heap+exit=debug
で代替可能。 - -XX:+TraceYoungGenTime
- -XX:+TraceOldGenTime
- Unified JVM Loggingの統合漏れ。
- JDK-8180286: Remove the launchers data model flags -d32/-d64
- 非推奨且つ廃止されていたデータモデルフラグが削除。
- -d32
- -d64
- JDK-8180421: Change default value of BiasedLockingStartupDelay to 0
-XX:BiasedLockingStartupDelay
のデフォルト値が 4000 (ms) から 0 に変更- 昔はBiasedLockの使用を遅延させた方が性能が良かったが最近の環境では差はなくなった。遅延を有効にした場合、VMに余分な作業のオーバーヘッドが発生するためデフォルトで遅延無しとなった。
- JDK-8185540: Empty path in -Xbootclasspath/a should be skipped rather than default to CWD
* ブートストラップクラスローダーは
-Xbootclasspath/a
で空要素を指定した場合は現在の作業ディレクトリ(CWD
)を検索していたが、Java 10からスルーするようになった * ちゃんと指定しましょう
- JDK-8166772: Touch keyboard is not shown for text components on a screen touch
- Windows 8以降のSwing/AWT テキストコンポーネントにてタッチキーボードを自動で表示するようになりました。デフォルトで有効なため動作の非互換性です
-Dawt.touchKeyboardAutoShowIsEnabled=false
を指定することで既存通り表示しないように設定可能 * Java 8u172から入る模様(バックポート一覧にはあるが動作未確認)
- JDK-8189131: Open-source the Oracle JDK Root Certificates
- OpenJDKにルートCA証明書のデフォルトセットが提供されました
- JDK-8172890: JEP 307: Parallel Full GC for G1
- G1のFull GCが並列化。youngとmixed collectionと同量の並列ワーカースレッド(parallel worker threads)が使用される。
- 旧実装はシングルスレッドのマークスイープコンパクトアルゴリズムだった。
- JDK-8185661: JNLP files won't launch from IE11 on Windows 10 Creators Update
- 64bit JRE をインストールしている Windows 10 Creators Update 適用後の IE 11 から、JNLPリンクをクリックしても Java Web Start アプリケーションは立ち上がらなくなりました。
- 64bit JREを消して32bit JREを入れよと言っているが…
- 9.0.4 にもリリースノートが打たれている
- バックポート先にJava 8 (8u172)にも遡及?(Java Web StartはOracle JDKの実装なので見れない)
- Oracle さーん?
- と書いた数日後にJava 11からJava Web Start(とApplet)は含めないと宣言してきた。https://blogs.oracle.com/java-platform-group/the-future-of-javafx-and-other-java-client-roadmap-updates
- JDK-8187147: Remove T2K from JavaFX in JDK 10
- Windows XPとVistaのために残されていたT2KラスタライザとICUレイアウトエンジンがJavaFXより削除
- JDK-8148421: Transport Layer Security (TLS) Session Hash and Extended Master Secret Extension
- JDK JSSEプロバイダのTLSセッションハッシュと拡張マスターシークレットの拡張機能(RFC 7627)のサポートが追加されました。
- Triple Handshake攻撃の対処。
-Djdk.tls.useExtendedMasterSecret=false
で拡張機能のネゴシエーションを無効にすることができる-Djdk.tls.allowLegacyResumption=false
で、セッションハッシュと拡張マスターシークレット拡張がネゴシエートされていない場合、短縮ハンドシェイクを拒否できる。-Djdk.tls.allowLegacyMasterSecret=false
で、セッションハッシュと拡張マスターシークレット拡張をサポートしていない接続を拒否できる- Java 6-9にもバックポートされている
- JDK-8186535: Remove deprecated pre-1.2 SecurityManager methods and fields (Remove項にもある)
- 非推奨である
java.lang.SecurityManager::checkMemberAccess
メソッドを、AllPermission
が与えられていない呼び出し元から呼んだ場合、SecurityException
をスローするように変更された。 java.lang.SecurityManager::checkPermission
メソッドを直接呼ぶようにすべき。
- 非推奨である
- JDK-8175883: bytecode generated for the enhanced for loop may block memory garbage collecting
- 拡張 for ループ構文のバイトコード生成が改善され、使用されなくなった iterator 変数が直ちにGCによって回収されることが可能になった
- テストコードを読むと解りやすい
- JDK-8177085: Accept including .conf files in krb5.conf's includedir
- krb5 1.15に追随し、
krb5.conf
にてincludedir <DIRNAME>
で指定したディレクトリの.conf
で終わるファイルも読み込むようになりました
- krb5 1.15に追随し、
- JDK-8186694: JShell: speed-up compilation by reusing compiler instances
- JShellの起動が早くなりました
- 特に大量の snippet と共に起動しようとすると、コンパイラインスタンスを都度立ち上げてたので遅かった
- JDK-5016517: Replace plaintext passwords by hashed passwords for out-of-the-box JMX Agent
- JMX agent のセキュリティ強化
- JDK-8185346: Relax RMI Registry Serial Filter to allow arrays of any type
- RMI Registry の組込シリアライゼーション(serialization)フィルタはコンポーネントタイプをチェックしていたが配列サイズのみチェックするようになった
- 最大配列サイズは1,000,000に増加した。overrideフィルタを用いてこのサイズは減少させることが可能
- これに伴い、
conf/security/java.security
設定ファイルが更新され、デフォルトの動作が変更された - 7 までバックポート一覧に入っているが動作未確認
- JDK-8191510: Bump class file version number to 54.0
- バージョンアップ恒例のクラスバージョン番号のインクリメント * 新しいバージョンでビルドしたものを古いバージョンで実行するとでてくるやつ