X

A blog about Oracle Technology Network Japan

Java 15の内側:5つのカテゴリに分かれた14個のJEP

Guest Author

JDK 15に追加される、Hiddenクラス、Sealedクラス、テキスト・ブロック、レコード、EdDSAといった多くの優れた機能

※本記事は、Alan Zeichick による "Inside Java 15: Fourteen JEPs in five buckets" を翻訳したものです。


 

August 28, 2020

本記事をPDFでダウンロード
 

Java 15には優れた機能が数多く搭載されています。2020年9月15日のリリースには、14個の重要なJDK拡張提案(JEP)が含まれています。本記事では、JEP自体に含まれる情報をもとに、新機能の概要を簡単にまとめたいと思います。
ここでは、14個のJEPを5つのカテゴリに分けています。詳しくは、それぞれのJEPのドキュメントをご覧ください。


楽しみな新機能:

  •   JEP 339:エドワーズ曲線デジタル署名アルゴリズム(EdDSA)
  •   JEP 371:Hiddenクラス


既存のJava SE標準への追加:

  • JEP 378:テキスト・ブロック
  • JEP 377:Zガベージ・コレクタ(ZGC)
  • JEP 379:Shenandoah:一時停止時間短縮型ガベージ・コレクタ(正式版)

レガシーJava SE機能の最新化:

  • JEP 373:レガシーDatagramSocket APIの再実装

新しいものへの期待:

  • JEP 360:Sealedクラス(プレビュー)
  • JEP 375:instanceofのパターン・マッチング(2回目のプレビュー)
  • JEP 384:レコード(2回目のプレビュー)
  • JEP 383:外部メモリ・アクセスAPI(2回目のインキュベータ)

機能の削除と非推奨化:

  • JEP 372;Nashorn JavaScriptエンジンの削除
  • JEP 374:バイアス・ロックの無効化と非推奨化
  • JEP 381:SolarisおよびSPARCポートの削除
  • JEP 385:RMIアクティブ化の削除に向けた非推奨化

 

楽しみな新機能

最初にお断りしておきますが、JEP 339で扱っているエドワーズ曲線デジタル署名アルゴリズム(EdDSA)は、暗号化に関して筆者が理解している範囲を少々上回っています。というより、完全に筆者の理解を超えています。しかし、このJEPは、既存のC言語実装であるECDSAよりも高パフォーマンスで、プラットフォームから独立したEdDSAの実装となるように設計されています。その重要な目的は、サイドチャネル攻撃を回避することです。


JDKのドキュメントには、以下のように書かれています。

EdDSAは最新の楕円曲線署名スキームで、JDKの既存の署名スキームに比べて有利な点がいくつかあります。このJEPの第1の目的は、RFC 8032で標準化されたとおりにこのスキームを実装することです。この新しい署名スキームは、ECDSAを置き換えるものではありません。

追加の実装の目的は以下のとおりです。

既存のECDSA実装(ネイティブCコードを使用したもの)よりもパフォーマンスが優れ、同じセキュリティ強度を備え、プラットフォームから独立したEdDSAの実装を開発します。たとえば、Curve25519を使用するEdDSA(セキュリティ・ビット数がおよそ126ビット)は、曲線secp256r1を使用するECDSA(セキュリティ・ビット数がおよそ128ビット)と同じくらいの処理時間となるはずです。

さらに、この実装ではシークレットによって分岐することはありません。これらの特性は、サイドチャネル攻撃を防ぐうえで大いに役立ちます。


これで皆さんは筆者以上の知識を得たはずです。近いうちに、EdDSAの解説記事がJava Magazineに掲載されることが期待できますね。

Hiddenクラス(JEP 371)とは、他のクラスのバイトコードから直接使用できないクラスです。Hiddenクラスを使うのは、実行時に動的にクラスを生成してリフレクション経由で間接的にそのクラスを使うフレームワークであると想定されています。動的に生成されたクラスは、限られた時間しか必要とされないかもしれません。したがって、そのようなクラスを、静的に生成されたクラスが生存している間ずっと保持し続けると、無駄なメモリ・フットプリントの増加につながる可能性があります。

また、動的に生成されたクラスは検出できません。名前によって独立して検出できると、問題になる可能性があります。動的に生成されたクラスは、静的に生成されたクラスの実装の詳細にすぎないという目的が損なわれるからです。

Hiddenクラスのリリースは、開発者が非標準APIである sun.misc.Unsafe::defineAnonymousClass を使わないようにするための土台となる作業です。オラクルは、将来的にこのクラスを非推奨にして削除することを予定しています。

 

既存の Java SE 標準への追加

JDK 13とJDK 14でのプレビューを経たテキスト・ブロック(JEP 378)は進化を続けます。テキスト・ブロックは複数行文字列リテラルであり、Project Amberによるものです。テキスト・ブロックにより、ほとんどのエスケープ・シーケンスを省略できるようになります。 

テキスト・ブロックでは、予測可能な方法で文字列が自動的に書式設定されますが、それが十分でない場合は、開発者が書式設定の方法を制御できます。2回目となる今回のプレビューでは、改行と空白を制御するための新しいエスケープ・シーケンスが2つ導入されています。たとえば、\<行終端文字>エスケープ・シーケンスによって、改行文字の挿入が明示的に抑制されます。


String literal =  "Lorem ipsum dolor sit amet, "+
        	      "consectetur adipiscing elit, " +
                  "sed do eiusmod tempor incididunt";

しかし今後は、\<行終端文字> を使うことにより、コードが読みやすくなります。


String literal = """
        	     Lorem ipsum dolor sit amet, \
	           consectetur adipiscing elit, \
        	     sed do eiusmod tempor incididunt\
	           """;

\s エスケープ・シーケンスを使うと、文字列に続く空白が削除されないようにすることができます。そのため、次の例は、各行の長さが厳密に5文字である、3行のテキストを表します(3行目のgreenはすでに長さが5文字なので、 \s は不要です)。


String colors = """
        red \s
        green
        blue\s\
        """;

Zガベージ・コレクタ(JEP 377)は、JDK 11で試験運用版機能として導入されました。今回のリリースで、試験運用版ではない正式版の機能となります。ZGCは、コンカレント、NUMA対応、低遅延のスケーラブルなガベージ・コレクタです。数テラバイトのヒープでも、ガベージ・コレクションによる一時停止が10ミリ秒未満になるように調整されています。オラクルのテストによれば、平均の一時停止時間は1ミリ秒未満、最大の一時停止時間は2ミリ秒未満です。図1に示すのは、Javaのパラレル・ガベージ・コレクタ、G1、ZGCの比較です。ZGCの一時停止時間は10倍に拡大しています。

図1: ガベージ・コレクタの一時停止時間の比較

ただし、多くのワークロードでは、G1(これが引き続きデフォルトです)の方がZGCよりもやや高速かもしれません。また、数百メガバイトしかない非常に小さなヒープでも、G1の方が高速かもしれません。そのため、どちらのガベージ・コレクタを使うべきかを確認するためには、自分で実際のワークロードを使ってテストする必要があります。

重要:ZGCは試験運用版ではなくなったため、使用時に-XX:+UnlockExperimentalVMOptionsを指定する必要はありません。

ZGCは、オラクルのOpenJDKビルドとOracle JDKに含まれます。ガベージ・コレクタのその他の選択肢として、Shenandoah(JEP 379)がいくつかのOpenJDKビルドで利用できます。
 

レガシー Java SE 機能の最新化

JEP 373では、レガシーDatagramSocket APIが再実装されています。これは主に、非常に古いコードの一部をリファクタリングすることが目的だと考えてください。このJEPによって、古くてメンテナンスしにくいjava.net.DatagramSocket APIとjava.net.MulticastSocket APIの実装が、よりシンプルでモダンな実装に置き換えられるからです。新しい実装は、メンテナンスやデバッグが容易なだけでなく、Project Loomの仮想スレッドでも動作するようになります。

非常に多くの既存コードがJDK 1.0で導入された古いAPIを使っているため、レガシー実装は削除されません。ちなみに、リファクタリングされたAPIがリグレッション・テストや一部の特殊ケースで問題を起こす場合は、JDK固有の新しいシステム・プロパティであるjdk.net.usePlainDatagramSocketImplを指定して、JDKでレガシー実装が使用されるように構成します。

 

新しいものへの期待

JDK 15では、Project Amberから生まれたSealedクラス(JEP 360)の第1回プレビューが行われます。SealedクラスおよびSealedインタフェース(「Sealed」は「封印された」という意味です)では、その拡張や実装が可能なクラスまたはインタフェースが制限されます。なぜこれが重要なのでしょうか。開発者は、特定のクラスやインタフェースを実装するコードを制御したいかもしれません。また、Sealedクラスによって、アクセス修飾子よりも宣言的にスーパークラスの使用を制限する方法も提供されます。次に例を示します。


package com.example.geometry;

public sealed class Shape
        permits com.example.polar.Circle,
                com.example.quad.Rectangle,
                com.example.quad.simple.Square {...}

Sealedクラスにする目的は、すべての許可済みサブクラスをクライアントのコードで把握できるようにすることです。特に、オリジナルのクラス定義が完全に内包的であることが求められており、かつ、許可されている場合にのみそのクラス(またはインタフェース)を拡張できるという仕組みを開発者が望まないといったユースケースもあるでしょう。

Sealedクラスには、いくつかの制約があります。

  • Sealed クラスとその許可済みサブクラスは、同じモジュールに配置しなければなりません。また、無名モジュールで宣言されている場合は、同じパッケージに配置しなければなりません
  • すべての許可済みサブクラスは、Sealed クラスを直接拡張しなければなりません
  • すべての許可済みサブクラスでは、スーパークラスから始まった Sealed クラス化をどのように継続するかを示す修飾子、つまり、final、sealed、non-sealed ( Sealed クラスでは、許可済みサブクラスでnon-sealedが宣言されるのを防ぐことはできません ) のいずれかを選ばなければなりません

JDK 15では、instanceofのパターン・マッチング(JEP 375)の2回目のプレビューも行われます。こちらも、Project Amberで開発されたものです。Java 14で第1回プレビューが行われましたが、その段階と比較して何も変更されていません。

この機能の目的は、instanceof演算子でパターン・マッチングを行い、Javaを強化することです。パターン・マッチングにより、プログラムに含まれる一般的なロジック(条件に応じた、オブジェクトからのコンポーネント抽出)をより簡潔かつ安全に表現できます。手引きとして、Mala Gupta氏のすばらしい記事「Java 14におけるinstanceofのパターン・マッチング」を紹介します。

レコード(JEP 384)は人気の機能であり、Java 15で2回目のプレビューが行われます。レコードは、不変データの透過的なキャリアとして動作するクラスです。新しいJEPでは、コミュニティからのフィードバックに基づいて微調整が行われています。また、ローカルなクラスとインタフェースで、いくつかの追加形態が新たにサポートされています。レコードもProject Amberによるものです。

レコード・クラスはオブジェクト指向の構造で、シンプルな値集合を表します。そのため、レコード・クラスを使うと、プログラマーは拡張可能な動作ではなく、不変データのモデリングに集中できます。レコードでは、equalsメソッドやアクセッサ・メソッドなどのデータ駆動型メソッドが自動的に実装されます。また、名前的型付けや移行の互換性など、長年にわたるJavaの原則も維持されます。言い換えるなら、不変データを含むクラスがある場合、レコードを使えばコーディングしやすく、読みやすくなります。

最後に紹介する新機能は、2回目のインキュベータ・リリースとなる外部メモリ・アクセスAPI(JEP 383)です。このAPIにより、JavaプログラムがJavaヒープ外の外部メモリに安全かつ効率的にアクセスできます。この機能の目的は、java.nio.ByteBufferおよびsun.misc.Unsafeの置き換えを始めることです。この機能は、Java APIと非Java APIの連携を向上させるProject Panamaの一部です。

JEPドキュメントには、このイノベーションが求められる必要性が以下のようにうまくまとめられています。

外部メモリへのアクセスとなると、開発者はジレンマに直面します。ByteBuffer APIのように、安全であるものの制限が存在する(そしておそらく効率が悪い)方法を選ぶべきでしょうか。それとも、安全性の保証を捨て、サポートされていない危険なUnsafe APIを採用すべきでしょうか。

このJEPによって、安全でサポート対象となる効率的な、外部メモリ・アクセス用のAPIが導入されます。外部メモリ・アクセス問題に的を絞ったソリューションが提供されるので、開発者は既存APIが持つ制限と危険性から解放されます。また、新しいAPIは最初からJIT最適化を意識して設計されているので、開発者はパフォーマンスの向上という恩恵も受けます。

 

機能の削除と非推奨化

以下の内容が議論を呼ぶことはないはずです。

JEP 372は、Nashorn JavaScriptエンジンの削除に関する内容です。Nashorn JavaScriptエンジンとそのAPI、そしてjjsツールは、Java 11で非推奨となり、今回のリリースで削除されます。

バイアス・ロックの無効化と非推奨化(JEP 374)では、競合しないロックのオーバーヘッドを減らすため、HotSpot JVMで使われている古い最適化技術を取り除く作業が始まります。歴史的に見て、ロックにバイアスをかけるという方法では、通常のロック技術と比べてパフォーマンスが著しく向上していました。しかし、パフォーマンス上の優位性は、かつてほど際立つものではなくなっています。最新のプロセッサでは、アトミックな命令を実行するコストが低くなっているためです。

バイアス・ロックにより、複雑なコードが数多く導入されました。そしてその複雑さは、Javaチームが同期サブシステムで大幅な設計変更を行う際の障害になっています。バイアス・ロックをデフォルトでは無効化する一方で、再有効化の選択肢を開発者に残すことで、将来のリリースで完全に削除することが合理的かどうかを判断したいとJavaチームは考えています。

JEP 381(SolarisおよびSPARCポートの削除)では、Solarisオペレーティング・システムおよびSPARCアーキテクチャ限定のソース・コードがすべて削除されます。他に述べるべきことはありません。

JEP 385(RMIアクティブ化の削除に向けた非推奨化)は、Java 8以降でオプションとなっている、リモート・メソッド呼出しの古い部分をJavaから徐々に取り除くものです。

RMIアクティブ化の使用は少なく、その数は減少しています。Javaチームは、新しく書かれるアプリケーションでRMIアクティブ化を使っているケースを認識していません。さらに、RMIアクティブ化を使っている既存のアプリケーションがほとんどないという証拠もあります。オープンソースのさまざまなコードベースを検索したところ、このアクティブ化に関連するAPIに言及している箇所はほとんどないことがわかりました。この数年間、RMIアクティブ化に関して外部からバグ・レポートが寄せられたことはありません。

Javaプラットフォームの一部としてRMIアクティブ化を維持することにより、継続的なメンテナンス・コストが発生し、RMIも複雑になります。RMIアクティブ化は、アクティブ化以外のRMIに影響を与えずに削除できます。RMIアクティブ化が削除されても、開発者にとってのJavaの価値は低下しません。削除によって低下するのは、JDKの長期的なメンテナンス・コストです。そのため、この機能の削除に向けた作業を始めるべきタイミングが来ていると言えます。


まとめ

Java 15では、JDKの6か月のリリース周期が継続されており、そこには一連の確かな新機能、機能変更、そしてプレビューおよびインキュベータが含まれています。Java 15では、ほとんどの開発者にとって優れた機能が数多く提供されます。この新リリースの感想をjavamag_us@oracle.comまで電子メールでお知らせいただくか、またはハッシュタグ#java15をつけてTwitterに投稿してください。

最後になりますが、8月中旬のJDK 15に関するWebキャスト(こちらから再生できます)のためにこのような大量の情報を集めてくれたことについて、オラクルのJava Platform Groupのプロジェクト管理担当シニア・ディレクターであるAurelio Garcia-Ribeyroに感謝をささげたいと思います。

 

さらに詳しく

 

Alan Zeichick

Java Magazine編集長。オラクルのContent Centralグループのエディター・アット・ラージ。メインフレームのソフトウェア開発者、テクノロジー・アナリストを経験した後、AI Expert、Network Magazine、Software Development Times、Eclipse Review、Software Test & Performanceの編集に携わった。Twitterのフォローは@zeichickから。

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.