こんにちは。 エキサイト株式会社の三浦です。
Javaで開発をする際、Spotlessを使用している方もいるのではないでしょうか。
このSpotlessですが、実は特定の状況下だとJava17で実行できない場合があります。
今回は、その状況と解決法について説明します。
Spotlessとは
Spotlessは、コードフォーマッタの1つです。
例えばJavaのGradleであれば、以下のように設定するだけで簡単に使えます。
build.gradle
// spotlessをimport plugins { id "com.diffplug.spotless" version "6.10.0" } spotless { java { // フォーマット設定を記述 } }
実行
./gradlew spotlessApply
これだけで簡単にコードをフォーマットしてくれます。
非常にお手軽で便利ですが、Java17で使用しようとするとエラーが発生する場合があります。
Java17で実行する方法
例えば、以下の設定をJava17で実行してみます。
spotless { java { removeUnusedImports() } }
すると、以下のエラーが起きてしまいます。
Caused by: java.lang.IllegalAccessError: class com.google.googlejavaformat.java.RemoveUnusedImports (in unnamed module ***) cannot access class com.sun.tools.javac.util.Context (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.util to unnamed module ***
Java17のひとつ前のLTSバージョンであるJava11では起きないのですが、Java17になる過程で一部の設定が変わり、このエラーが出るようになったようです。
このエラーを回避するには、JVMに引数を渡す必要があります。
org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
これにより、問題なく実行できるようになります。
最後に
Javaのバージョンアップは、さまざまな新機能が使えるようになったりパフォーマンスが良くなったりなどいいことがたくさんありますが、一方で今回のように調整が必要な部分も出てきます。
とはいえ古いバージョンはいずれサポートされなくなっていくので、頑張ってバージョンアップしていくようにしましょう。