Apache Foundationは、Groovyのバージョン3.0をリリースした。これには、新しいパーサー、パッケージ名の変更、拡張されたエルビス演算子、do/whileループ、配列の初期化、ラムダ、メソッド参照などのJava構文のサポートなどの新機能が含まれる。Groovy 3.0では、アプリケーションをビルドするためにJDK9以降が必要であり、サポートされているJavaランタイム環境 (JRE) の最小バージョンはJDK8である。
Groovy 3.0には、コードネームParrotという新しいGroovyパーサが導入されている。その名前は、現在の遺産であるAntlr2パーサからの「parrot」出力への意図に由来している。Parrotはより柔軟で保守しやすいように設計されており、追加の構文オプションと言語機能もサポートしている。
2018年夏に遺産のパーサとParrotパーサの違いについて尋ねたとき、Object Computing (OCI) のプリンシパルソフトウェアエンジニアであり、GroovyコミッターでApache GroovyのバイスプレジデントであるPaul King氏はInfoQに次のように語っている:
「Parrot」パーサについて話すときは、Groovy 3のコンパイラの初期段階を完全に刷新したことについて話します。はるかに柔軟になり、最近の十分にサポートされたテクノロジーを使用するように再設計されました。この作業により、Groovyは迅速に進化する絶好の位置に置かれます。つまり、Javaからの変更を組み込んで、Javaとの「カットアンドペースト」互換性とネイティブのGroovyの変更を組み込むことができます。
「Indy」のサポートについて話すとき。これはすべて、コンパイラの後の段階で生成される種類のバイトコードに関するものです。Groovyバージョン 2.0から2.5では、「クラシック」Groovyバイトコードと「Indy」バージョンの生成をサポートしています。Indyバージョンは、JDK7で導入された「INvokeDYnamic」バイトコード命令を利用します。
Parrotパーサはデフォルトで有効になっており、遺産パーサは現在非推奨のままである。Parrotでコンパイルできない問題のあるコードがある開発者は、コマンドラインにシステムプロパティ -Dgroovy.antlr4=false
を追加することで、コードを無効にし、遺産パーサに戻すことができる。ただし、遺産パーサは最終的にGroovy 4.0で削除される。
JDK9で最初に導入されたJavaPlatform Module System (JPMS) をサポートし、ファーストクラスモジュールと見なされる新しいGroovyモジュールに対応するために、いくつかのGroovyクラスが別のパッケージ名に移動された。例えば:
groovy.util.XmlParser
をgroovy.xml.XmlParser
に移動するgroovy.util.XmlSlurper
をgroovy.xml.XmlSlurper
に移動するgroovy.util.GroovyTestCase
をgroovy.test.GroovyTestCase
に移動する
下位互換性のために、これらのクラスは両方のパッケージ名で使用できるが、遺産の名前空間 (移動元パッケージ名) は最終的にGroovy 4.0で削除される。
2019年夏にJavaコミュニティで利用できるJDK14早期アクセス (EA) は、予定される新機能のプレビューを公開した。ただし、JDK 14 EA、Groovy 2.5.x、およびGradle 5.5.xを組み合わせて使用すると、予期しない動作がいくつか発見された。コマンドラインで groovy -version
と gradle clean
などのGradleタスクを実行すると、例外がスローされる。興味深いことに、gradle -version
を実行すると予想どおりに機能する。
Gradleは、Mavenで使用されるXMLを優先して、プロジェクト構成にGroovyベースのドメイン固有言語を利用する。根本的な問題は、GradleがGroovy 2.5に依存していることである。これは、JDK14で削除された java.lang
のプライベートコンストラクタをリフレクションを用いて呼び出している。
Oracleのシニアソフトウェア開発マネージャであるStephen Felts氏は、次のように文書化している:
JDK14 b8は壊れています。これは groovy-git/src/main/org/codehaus/groovy/vmplugin/v7/Java7.java のバグです。
Lookupのコンストラクタの1つをハッキングしているようです。Lookupオブジェクトでテレポートする問題を修正する作業の一部としてこの領域をリファクタリングしたようですが、コンストラクタはプライベートであり、JDK 14には存在しません。
try/catchブロックがありますが、SecurityExceptionをキャッチしています。JDK9から、このタイプのエラーは新しいJDK9ランタイム例外をスローします。互換性のあるコードを作成するためには、正確な例外をキャッチすることはできない代わりに catch (RuntimeException) を使用します。
この問題はGroovy 3.0の進化とともに解決されましたが、重大な変更につながった。King氏は、Apache JIRAでのこれらの重大な変更について質問され、次のように回答した:
これは、Groovy 3.0への移行の一環として個々のプロジェクトがどれだけ取り組むかによって異なります。
ほんの一例として、モジュール内のJDK9以降のパッケージ命名規則の一部として、
groovy.util.XmlParser
は最終的にgroovy.xml.XmlParser
に名前を変更する必要があります。そうしないと、groovy
モジュールとgroovy-xml
モジュールの両方にgroovy.util
パッケージがあります。Groovy 3.0の場合、Groovyの「モジュールjar」はJDKモジュールに厳密に準拠しているわけではなく、実際には両方のクラスを使用できます。したがって、GradleやCodeNarcなどのプロジェクトの場合、XmlParserを使用する場合は、今はほとんど何もせずに古いクラスを使用することに決めることができます (ただし、Groovy 4に移行するときにやるべきことがいくつかあります) 、後で余分な作業を避けるためにはもう少しできることがあります。
King氏は、この最新リリースの課題とGroovy 4.0で何が期待できるかについてInfoQに話した。
InfoQ: Groovy 3.0について読者と何を共有したいですか ?
King氏: Groovy 3は、約600のバグ修正、改善、新機能を備えた大きなリリースです。80以上の新しいGDKメソッド、Groovydocを埋め込むための方法の改善、および新しいAST変換があります。しかし、このリリースは、その真新しいパーサがよく知られています。
新しいパーサはほとんどが内部の詳細であり、新しいパーサははるかに柔軟であるため、Groovyチームの作業が楽になります。新しいパーサを使用して、新しい演算子 ('
===
' 参照等式演算子、'!in
' および '!instanceof
' 演算子、エルビス代入演算子など) などのいくつかの新機能を言語に追加しました。安全なインデックス作成もサポートされています。たとえば、
list?[index]
は、リストがnull
の場合にnull
を返します。ラムダ式、メソッド参照、var
予約型、do/whileループ、一部の配列初期化構文、インターフェイスのデフォルトメソッド、さらにはJDK14の新しい「\s
」バックスラッシュエスケープシーケンスなど、現在サポートされているJava互換の変更も多数あります。これらすべてのJava互換の変更により、Groovy 3の大部分がJavaに追いついていたように見えるかもしれません。それは本当に起こっていることではありません。Groovyは、特定のJava構造をコーディングするためのより簡潔で慣用的な方法をサポートすることがよくありますが、Java構文もサポートすることで、JavaからGroovyにアクセスする開発者の学習曲線が大幅に短縮されます。
InfoQ: JDK14、Groovy 2.5.x、Gradle 5.5.xの使用に関する問題につながる、Groovy 3.0の最小ビルド要件としてのJDK9に関連する課題は何でしたか ?
King氏: 関連する問題がいくつかありました:
- JDK9以降では、いわゆる内部クラスの非推奨と削除が開始されました。その一部はGroovy (および他の多くのライブラリ) で使用されていました。これらの内部クラスから離れました。
- JDK9以降では、動的言語に対応していない不正アクセス警告を発行するアプローチを使用していました。今は、親またはインターフェイスのメソッドシグネチャを介してメソッドを呼び出すことがあります (Clojureで使用されるアプローチと同様)
- Groovyはバイトコードの読み取りを他のライブラリ (ASMなど) に依存しているため、これらのライブラリが特定のJDKバージョンをサポートするまで待つ必要があります。
- GroovyにはJDKプラグインシステムがあり、JDKのバージョンごとに異なるコードを数か所で使用できます。後のJDKバージョンにはないかもしれない古いクラスを遅延ロードすることをよりスマートにしました。
この作業はGroovy 3を対象としていましたが、一部はGroovy 2.5.xにバックポートされました。
InfoQ: その結果、GradleはGroovy 3.0にリベースすることを余儀なくされますか ?
King氏: 現在、GradleがJDK14と連携するために必要なすべての機能はGroovy 2.5.xにあるため、Groovy 3に移行するようにすぐにプレッシャーをかけることはありません。
ただし、Groovy 3に移行すると、Gradleユーザはビルドスクリプトでラムダ式などのGroovy 3機能を使用できるようになります。また、Gradleは、違法な警告メッセージを表示する構成設定をオフにすることができます。
最終的には、Groovy 3以降でのみサポートされるJDKバージョンが登場するため、Gradleのアップグレードを検討することをお勧めします。
Grails、Micronaut、SpockなどのGroovyエコシステムの他のライブラリによるGroovy 3への移植の進展に満足しています。
InfoQ: Groovy 4.0ではどのような機能が計画されていますか ?
King氏: 一部の作業は、主に内部リファクタリングです。Groovyの最近のバージョンでは、古典的なバイトコードだけでなく、動的 (Indy) フレーバーのバイトコードの呼び出しもサポートされています。Groovy 4はすべてIndyベースになります。
Groovy 3は、すでに述べた新しいパーサをサポートしますが、古いパーサに戻すこともできます。Groovy 4は、新しいパーサのみをサポートします。
新機能の面では、多くの機能を検討していますが、そのうちのいくつかはまだ実験段階です。.NETの統合言語クエリ (LINQ) に相当するGroovy、Groovyでの
module-info
ファイルの書き込みのネイティブサポート、Groovyでのレコードの書き込みのネイティブサポート、プラットフォームロギングのサポートの改善、およびJavaのフラグメントで機能する新しいJavaShellクラスを検討しています。また、Java 12/13スイッチ式のネイティブサポートを検討することもできます (ただし、Groovyの既存のスイッチはさまざまな点でより強力です) 。
InfoQ: JavaおよびGroovyコミュニティはいつGroovy 4.0のアルファ版およびベータ版を見ることができますか ?
King氏: Groovy 4の最初のアルファ版を間もなくリリースする準備ができています。完全には程遠いので、いつリリースするかを決め、適切な期待を設定することが重要です。今後数か月以内にリリースされる予定です。
InfoQ: Groovyの今後の展望は他にありますか ?
King氏: ユーザが生産性をさらに向上させたいと考えているシナリオでは、Groovyの改善を引き続き検討します。
一部のユーザは、パフォーマンスを向上させるためにGraalVMでGroovyを使用していますが、動的言語には理想的ではありません。GroovyをGraalVMでより良く機能させる方法を見ていきます。また、データサイエンティストによるGroovyの採用も見られているため、今後もサポートを改善していきます。
間違いなく、JVM言語としてのGroovyの最大の貢献は、その拡張性です。この拡張性を使用して、Groovyの動的な性質と静的な性質の両方を継続的に改善します。
Groovyは、Maven CentralとBintrayからダウンロードされたGroovyアーティファクトの数が5億を超えたため、今月のマイルストーンを祝福する。Groovy 3.0はダウンロードページからダウンロードできる。この最新リリースの詳細については、リリースノートを参照してください。開発者は、Groovy 4.0でのJPMSサポートの改善を期待でき、アルファ版がまもなくリリースされる予定である。
リソース
- Apache Releases Groovy 2.5 and Preview of Groovy 3.0、InfoQ (2019年7月12日)