torutkのブログ

ソフトウェア・エンジニアのブログ

IntelliJ IDEA 2023.3 で Java 21 Preview機能を使う

IntelliJ IDEA 2023.3 と Java 21

先日リリースされた、IntelliJ IDEA 2023.3では、Java 21対応が完全サポートと謳われています。

9月に書いたブログ(下記)では、IntelliJ IDEA 2023.2.1でOpenJDK 21のPreview機能であるJEP 445 Unnamed Classes and Instance Main Methods の構文を認識できなかったと書きました。その後も2023.2.5までは未対応でした。

今回、2023.3になってどうなったかを見てみます。

torutk.hatenablog.jp

IntelliJ IDEA 2023.3 で JEP 445

New Projectを作成

IntelliJ IDEAの[File]メニュー > [New] > [Project...] を選択し、「New Project」ダイアログを表示します(下図)。

  • ① プロジェクト名を入力、この名前がディレクトリ名、生成されるJARファイルの基底名などに使われます。
  • ② プロジェクトディレクトリを作成する親ディレクトリを指定します。
  • ③ このプロジェクトで開発対象とするプログラミング言語を指定します。
  • ④ このプロジェクトのビルド・実行・デバッグ・配布などの活動に使うビルドツールを指定します。
  • ⑤ このプロジェクトのビルド・実行に使うJDKを指定します。
  • ⑥ ビルドツールに④でGradleを指定したとき、Gradleのビルド定義ファイルの記述に使うDSLの種類を指定します。
  • ⑦ 追加設定をするために、Advanced Settingsの先頭の[>]をクリックし追加設定を表示します。
  • ⑧ このプロジェクトが使うビルドツールGradleの共有方法を指定します。通常はWrapperを使用します。
  • ⑨ このプロジェクトで生成するアーティファクト(成果物)のGroupIdを指定します。成果物のオーナーを識別する目的で使われます。Javaの場合、パッケージ名に使用する組織(オーナー)のドメイン名に基づく部分を抽出して使用することが多いです。その下のArtifactIdは、通常①で指定したプロジェクト名と同じものが入っていますのでそのまま使います。

プロジェクトが生成されました。build.gradle.ktsが表示されます。

mainメソッドを記述

JEP 445では、無名パッケージのjavaソースファイルに、クラス定義なしに直接 メソッドなどを記述できます。 そこで、ソースディレクトリ( src/main/java/)の下に新規Javaソースファイルを作成します。

  • 左側ペインの src > main > java を選択し右クリックで、New > Java Class を選択して「New Java Class」ダイアログを表示
  • 名前にHelloとつける

では、Hello.java ファイルにmainメソッドを記述します。

エラーが出ています。OpenJDK 21では、JEP 445 は Preview機能なのでビルドするにはコンパイルオプションでPreview機能を有効にする必要があります。 IntelliJ IDEAでは、[File]メニュー > [Project Structure]で「Project Structure」ダイアログを表示し、Language level欄で[21 (Preview) ...]を設定します。

実行(IntelliJ IEA上から)

mainメソッドの宣言行にある緑枠の右三角アイコンをクリックすると、mainメソッドを実行します。

しかし、エラーとなってしまいました。先程の、Lanugage levelの設定とは別に、Gradleの定義でPreviewを有効にする必要がありそうです。

  • 試行1 Settings > Build, Execution, Deployment > Compiler > Java Compiler を開き、[Additional command line parameters]に、--enable-preview を設定した。結果、エラーが出るのは変わらず。

  • 試行2 Gradle Documentに記載のタスク定義を追記

次のドキュメントの Enabling Java preview features の記載の定義を、build.gradle.ktsに追記します。

Building Java & JVM projects

tasks.withType<JavaCompile>().configureEach {
    options.compilerArgs.add("--enable-preview")
}

tasks.withType<Test>().configureEach {
    jvmArgs("--enable-preview")
}

tasks.withType<JavaExec>().configureEach {
    jvmArgs("--enable-preview")
}

この定義を追加することにより、コンパイル・実行が可能となりました。 IntelliJ IDEA上から実行するときは、Runメニュー、またはmainメソッドの宣言行の三角アイコンから可能です。

実行(コマンドライン

コマンドラインから実行する場合、この時点の記述ではGradleのタスクで実行は用意されていないので、javaコマンドにパスを指定して実行する必要があります。

hello % ./gradlew build    

> Task :compileJava
  :
BUILD SUCCESSFUL in 927ms
2 actionable tasks: 2 executed
hello % ls build/libs 
hello-1.0-SNAPSHOT.jar
hello % java --enable-preview -cp build/libs/hello-1.0-SNAPSHOT.jar Hello
Hello, Java 21 Preview world.
hello % 

まとめ

IntelliJ IDEAでGradleをビルドツールに使うプロジェクトで OpenJDK のプレビュー機能を使ってプログラミングする場合、

  • Project Structureで、Language level に Previewを有効にするバージョンを指定する
  • Gradleのビルド定義(build.gradle.kts)に、コンパイル・実行時に javaVMオプション --enable-previewを指定する記述を追記する

を行います。