エンジニアの友野です。久しぶりのポストですが小ネタです。
日頃、開発時はIDE上でJavadocを参照していたので気にしていませんでしたが、ふと、現状整理するために俯瞰した全体のJavadocドキュメントが欲しくなりました。Lombokはコンパイル時にコード生成するため、Javadoc生成時にはLombokが生成するコードがドキュメント化されません。ちなみに、onMethod
のように生成したコードにアノテーション付与などするオプションではそもそもJavadoc生成時にビルドエラーになりました。
Lombokにはアノテーションからコード生成するdelombok
という機能があります。つまり、delombok
してからJavadocを生成すればLombokが生成したコードのJavadoc化ができるはず。ということで試してみました。
環境
本記事のサンプルコードは以下の環境で動作確認しています。
JVM: OpenJDK Runtime Environment Corretto-11.0.12.7.2 (build 11.0.12+7-LTS) Gradle: 6.6.1 Lombok: 1.18.12
プラグインの存在
まず初めに、gradle-lombokというプラグインが存在します。このプラグインは以下の機能を提供しており、これを使えばやりたいことは簡単にできます。
it adds the Lombok dependency to the classpath
it simplifies the Eclipse IDE installation
it offers support for delomboking
(訳)
Lombokの依存関係をクラスパスに追加
Eclipse IDEへのインストールの簡易化
delombokのサポート
しかし、以下のいくつかの理由で、このプラグインを参考に自分で書いてみることにしました。
- すでにLombokは依存関係に追加済み
- 開発で使用しているIDEはIntellij
delombok
以外の機能は使わなさそう- プラグインのコードを見るとシンプルなJavaExecタスクである
- このプラグインは開発停止中、不具合対応のみ行う状態である
delombokタスクの実装
JavaExecタスクということは、通常のjavaコマンドによる実行をスクリプトに置き換えればうまくいきます。javaコマンドでdelombokを実行するのは以下の通りです(公式サイトから引用)。src
がdelombok対象のディレクトリ、src-delomboked
がdelombok結果を格納するディレクトリです。
$ java -jar lombok.jar delombok src -d src-delomboked
これをJavaExecタスクにすると以下のように書けます。lombok.jarはすでにコンパイルのクラスパスに含まれるので、mainを直接指定しています。argsでdelombokを文字列で渡すことで、上記コマンドラインと同じ結果が得られます。
今回はプロダクションコードのJavadocだけで良いので、ソースにはsrc/main/java
を指定しました。
task delombok(type: JavaExec, dependsOn: compileJava) { ext.outputDir = file("$buildDir/delombok") classpath = sourceSets.main.compileClasspath + sourceSets.main.output.generatedSourcesDirs main = 'lombok.launch.Main' args('delombok', 'src/main/java', '-d', outputDir) doFirst { outputDir.deleteDir() } }
JPAのメタクラスをコンパイルの依存に含んでいるので、compileJava
タスクに依存させてannotationProcesser
の出力先も含めていますが、Javadoc出力のためだけであれば、これがなくともdelombok
タスクでエラーが出るだけなので動作には問題ありません(気持ちの問題だけ)。
Javadocタスクの設定
次にJavadocを出力する設定です。javaプラグインをインポートしていればタスク定義はすでにあるので、設定だけ追加します。
apply plugin: 'java' /* JavadocでJava8以降のタグを出力するためのオプション */ def tagOptions = ["apiNote:a:API Note:", "implSpec:a:Implementation Requirements:", "implNote:a:Implementation Note:"] /* Javadoc生成時のクラスパス */ def javadocClasspath = sourceSets.main.compileClasspath + sourceSets.main.output.generatedSourcesDirs + files("$buildDir/delombok") javadoc { dependsOn([compileJava, delombok]) classpath = javadocClasspath source = delombok.outputDir options.tags = tagOptions failOnError = false }
実行は以下の通りです。
$ ./gradlew javadoc
これでdelombokしたソースからJavadocを出力できました!
今回はjavadoc
の設定で例示しましたが、特定のクラス群だけフィルタしたい場合などは別のJavadoc
タスクを定義して、source
に渡す対象を変えてあげれば可能です。
それでは良いJavadocライフを!