Java10でLombokを使ったプロジェクトをGradleビルドする

業務プロジェクトのJavaのバージョンアップは8→11を目論んでいますが、新しいJavaの機能にも少しずつ慣れていかなくてはと思ってます。

というわけで、あるプロジェクトを試しにJava10でビルドしてみたところ、Lombokで躓いたのでその解消方法についてのメモです。
基本的には、エラーが出たらエラー内容をきちんと読んで、一つずつ解消していくしかない、という当たり前の結論になりました。

環境

元のプロジェクトのバージョンとバージョンアップ後の状況はこんな感じ。

バージョンアップ前 バージョンアップ後
Java 1.8.0_172 10.0.1
Gradle ※ 3.5.1 4.7
Lombok 1.16.10 1.16.22

※ Gradleは、Java10だと以下のエラーでビルドができないので、上げています。

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine java version from '10.0.1'.

Lombokの最新Java対応状況

ちなみにLombokですが、今年の2月頃の状況としては、以下のページに書かれている通り、Java10 Early Access では動かなかったようです。

https://qiita.com/tmurakam99/items/b5ffe7f18bc06577f619qiita.com

LombokJDK の内部クラスにどっぷり依存しているので、JDKバージョンアップの度に追従が大変。JDKだけじゃなくてIDEの実装にも依存がある。
(略)
実際、OpenJDK10 Early Access ではすでに動かなくなってます。うはー

試したところ、Lombok 1.16.10のままで --stacktrace をつけてビルドすると、スタックトレースに以下のようなエラーが出力されました。

Caused by: java.lang.ClassNotFoundException: com.sun.tools.javac.code.TypeTags
        at lombok.launch.ShadowClassLoader.loadClass(ShadowClassLoader.java:418)
        at lombok.javac.JavacTreeMaker$SchroedingerType.getFieldCached(JavacTreeMaker.java:156)
        at lombok.javac.JavacTreeMaker$TypeTag.typeTag(JavacTreeMaker.java:244)
        at lombok.javac.Javac.<clinit>(Javac.java:154)
        ... 75 more

最新の1.16.22では、JDK10でコンパイルできるようになったようなので、試してみました。

Lombok1.16.22でビルドしてみる

早速ビルドすると、以下のようなコンパイルエラーが大量に出力…。

エラー: コンストラクタ Hoge()はすでにクラス Hogeで定義されています
@NoArgsConstructor
^

changelogを見ると、

FEATURE: Private no-args constructor for @Data and @Value to enable deserialization frameworks (like Jackson) to operate out-of-the-box. Use lombok.noArgsConstructor.extraPrivate = false to disable this behavior.

とあり、 @Data@Value アノテーションを付けた場合、privateな引数なしコンストラクタが作られるので、明示的に @NoArgsConstructor でpublicな引数なしコンストラクタを作ろうとすると、二重定義でエラーになってしまうみたいですね。

というわけで、メッセージに書かれている通り、プロジェクトの直下に lombok.config というファイルを作って、

lombok.noArgsConstructor.extraPrivate = false

と追記することで、今まで通りビルドできるようになりました。

Gradleのwarningも解消する

ビルドする過程でGradleをバージョンアップしたのですが、ビルド時にコンソールに

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.

Detecting annotation processors on the compile classpath is deprecated and Gradle 5.0 will ignore them.

という形の警告が表示されました。これを解消するには、dependenciesにannotationProcessorを追加すればOKです。

  dependencies {
      annotationProcessor "org.projectlombok:lombok:1.16.22"  // これを追加
      compileOnly "org.projectlombok:lombok:1.16.22"
  }

参考記事) java - Gradle deprecated annotation processor warnings for lombok - Stack Overflow