Gradle を使った Querydsl JPA のコード生成

今回は Querydsl JPA のコード生成を Gradle で実施してみました。

ソースは http://github.com/fits/try_samples/tree/master/blog/20150322/

はじめに

Querydsl JPA では JPA のエンティティクラスを元に Querydsl JPA 用のコードを自動生成して使います。

この場合のコード生成は querydsl-apt モジュールに含まれているアノテーションプロセッサ com.querydsl.apt.jpa.JPAAnnotationProcessor を javac のコンパイルオプションへ指定するだけです。

javac -processor com.mysema.query.apt.jpa.JPAAnnotationProcessor ・・・

Gradle の場合でも同様に上記コンパイルオプションを使用します。

(a) compileJava タスクでコード生成とコンパイルを実施

まずは、compileJava タスクの実行時に Querydsl のコード生成とコンパイルの両方を実施してみます。

下記 (1) のように compileJava の options.compilerArgsコンパイルオプション -processor com.mysema.query.apt.jpa.JPAAnnotationProcessor を追加します。

こうすることで、src/main/java 内の JPA エンティティクラスを元に destinationDir プロパティ値のディレクトリ (デフォルトでは build/classes/main) へ Querydsl JPA 用のソースファイルを自動生成し、コンパイルを実施します。

デフォルトでは destinationDir 内の全ファイルを JAR ファイルへ格納してしまいますので、下記の (2) では jar タスクの excludes を使って Querydsl が生成したソースファイルを除外するようにしています。

build.gradle
apply plugin: 'java'

repositories {
    jcenter()
}

configurations {
    apt
}

dependencies {
    // Querydsl JPA のコード生成モジュール
    apt 'com.mysema.querydsl:querydsl-apt:3.6.2'

    compile 'com.mysema.querydsl:querydsl-jpa:3.6.2'
    compile 'javax:javaee-api:7.0'
}

compileJava {
    classpath += configurations.apt

    // (1) アノテーションプロセッサの利用設定
    options.compilerArgs += [
        '-processor', 'com.mysema.query.apt.jpa.JPAAnnotationProcessor'
    ]
}

jar {
    // (2) 自動生成したソースファイルを jar ファイルから除外するための設定
    excludes << '**/*.java'
}

ビルド結果は以下の通りです。

ビルド例
> gradle build

:compileJava
注意:Running JPAAnnotationProcessor
注意:Serializing Entity types
注意:Generating sample.model.QProduct for [sample.model.Product]
注意:Running JPAAnnotationProcessor
注意:Running JPAAnnotationProcessor
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL

JPA 用のエンティティクラス src/main/java/sample/model/Product.java を元に build/classes/main/sample/model/QProduct.java ファイルを生成し、ビルドを行っています。

ビルド結果の JAR ファイルは以下のような内容になります。

JAR ファイルの内容例
  • sample/model
    • Product.class
    • QProduct.class
  • META-INF
    • MANIFEST.MF

(b) 別タスクでコード生成

次は、Querydsl のコード生成を別タスク (下記の generate) で実施するようにしてみます。

javac のコンパイルオプションで -proc:only とすれば、コンパイルを実施せずアノテーションプロセッサだけを実施するようになりますので、これを利用します。

JavaCompile を type へ指定したタスクを定義して source・classpath・destinationDir (コード生成の出力先) を設定し、コンパイルオプションへ -proc:only を追加します。

あとは compileJava タスクのコンパイル対象ソースへ Querydsl コード生成先ディレクトリを追加するだけです。 (タスクの依存設定は必要に応じて実施)

build2.gradle
apply plugin: 'java'
// コード生成先
def qdslDestDir = 'src/main/qdsl-generated'

repositories {
    jcenter()
}

configurations {
    apt
}

dependencies {
    apt 'com.mysema.querydsl:querydsl-apt:3.6.2'

    compile 'com.mysema.querydsl:querydsl-jpa:3.6.2'
    compile 'javax:javaee-api:7.0'
}

// Querydsl JPA コード生成用のタスク定義
task generate(type: JavaCompile) {

    source = sourceSets.main.java
    classpath = configurations.compile + configurations.apt
    // コード生成の出力先を設定
    destinationDir = new File(qdslDestDir)

    options.compilerArgs += [
        '-proc:only', // アノテーションプロセッサのみ実施するための設定 (コンパイルしない)
        '-processor', 'com.mysema.query.apt.jpa.JPAAnnotationProcessor'
    ]
}

compileJava {
    dependsOn generate
    // コンパイル対象ソースへコード生成先ディレクトリを追加
    sourceSets.main.java.srcDir qdslDestDir
}

clean {
    delete qdslDestDir
}

ビルド結果は以下の通りです。

アノテーションプロセッサを compileJava タスクの前に実行している以外は先程の (a) と同じです。 (当然ながら JAR ファイルの内容も同じです)

ビルド例
> gradle -b build2.gradle build

:generate
注意:Running JPAAnnotationProcessor
注意:Serializing Entity types
注意:Generating sample.model.QProduct for [sample.model.Product]
注意:Running JPAAnnotationProcessor
注意:Running JPAAnnotationProcessor
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL