English 中文(简体)
Generating JPA2 Metamodel from a Gradle build script
原标题:

I m trying to set up a Gradle build script for a new project. That project will use JPA 2 along with Querydsl.

On the following page of Querydsl s reference documentation, they explain how to set up their JPAAnnotationProcessor (apt) for Maven and Ant.

I would like to do the same with Gradle, but I don t know how and my beloved friend did not help me much on this one. I need to find a way to invoke Javac (preferably without any additional dependencies) with arguments to be able to specify the processor that apt should use (?)

最佳回答

I did not test it but this should work:

repositories {
    mavenCentral()
}
apply plugin:  java 
dependencies {
   compile(group:  com.mysema.querydsl , name:  querydsl-apt , version:  1.8.4 )
   compile(group:  com.mysema.querydsl , name:  querydsl-jpa , version:  1.8.4 )
   compile(group:  org.slf4j , name:  slf4j-log4j12 , version:  1.6.1 )
}

compileJava {
    doFirst {
        Map otherArgs = [
            includeAntRuntime: false,
            destdir: destinationDir,
            classpath: configurations.compile.asPath,
            sourcepath:   ,
            target: targetCompatibility,
            source: sourceCompatibility
        ]
        options.compilerArgs = [
             -processor ,  com.mysema.query.apt.jpa.JPAAnnotationProcessor ,
             -s , "${destinationDir.absolutePath}".toString()
        ]
        Map antOptions = otherArgs + options.optionMap()
        ant.javac(antOptions) {
            source.addToAntBuilder(ant,  src , FileCollection.AntType.MatchingTask)
            options.compilerArgs.each {value ->
                compilerarg(value: value)
            }
        }
    }
}

Hope it helps.

问题回答

While I have no problem with the use gradle makes of Ant, I agree with the original poster that it is undesirable in this case. I found a github project by Tom Anderson here that describes what I believe is a better approach. I modified it a small amount to fit my needs (output to src/main/generated) so that it looks like:

sourceSets {
     generated
}

sourceSets.generated.java.srcDirs = [ src/main/generated ]

configurations {
     querydslapt
}

dependencies {     
    compile  mine go here 
    querydslapt  com.mysema.querydsl:querydsl-apt:2.7.1 
}

task generateQueryDSL(type: Compile, group:  build , description:  Generates the QueryDSL query types ) {
         source = sourceSets.main.java
         classpath = configurations.compile + configurations.querydslapt
         options.compilerArgs = [
                "-proc:only",
                "-processor", "com.mysema.query.apt.jpa.JPAAnnotationProcessor"
         ]
         destinationDir = sourceSets.generated.java.srcDirs.iterator().next()
}
compileJava.dependsOn generateQueryDSL

This approach makes a lot more sense to me than the other, if it does to you too, then you have another option for querydsl generation.

This guy s gist worked for me: https://gist.github.com/EdwardBeckett/5377401

sourceSets {
    generated {
        java {
            srcDirs = [ src/main/generated ]
        }
    }
}

configurations {
    querydslapt
}

dependencies {
    compile  org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final 
    compile "com.mysema.querydsl:querydsl-jpa:$querydslVersion"
    querydslapt "com.mysema.querydsl:querydsl-apt:$querydslVersion"
}

task generateQueryDSL(type: JavaCompile, group:  build , description:  Generates the QueryDSL query types ) {
    source = sourceSets.main.java
    classpath = configurations.compile + configurations.querydslapt
    options.compilerArgs = [
            "-proc:only",
            "-processor", "com.mysema.query.apt.jpa.JPAAnnotationProcessor"
    ]
    destinationDir = sourceSets.generated.java.srcDirs.iterator().next()
}

compileJava {
    dependsOn generateQueryDSL
    source generateQueryDSL.destinationDir
}

compileGeneratedJava {
    dependsOn generateQueryDSL
    options.warnings = false
    classpath += sourceSets.main.runtimeClasspath
}

clean {
    delete sourceSets.generated.java.srcDirs
}

idea {
    module {
        sourceDirs += file( src/main/generated )
    }
}

Here is simple setup that works and integrates seamlessly with netbeans. Javac will basicly do all the job needed without much intervention. The rest are small treaks that will make it work with IDEs like Netbeans.

apply plugin: java 

dependencies {
    // Compile-time dependencies should contain annotation processors
    compile(group:  com.mysema.querydsl , name:  querydsl-apt , version:  1.8.4 )
    compile(group:  com.mysema.querydsl , name:  querydsl-jpa , version:  1.8.4 )
    compile(group:  org.slf4j , name:  slf4j-log4j12 , version:  1.6.1 )
}

ext {
    generatedSourcesDir = file("${buildDir}/generated-sources/javac/main/java")
}

// This section is the key to IDE integration.
// IDE will look for source files in both in both
//
//  * src/main/java
//  * build/generated-sources/javac/main/java
//
sourceSets {
    main {
        java {
            srcDir  src/main/java 
            srcDir generatedSourcesDir
        }
    }
}

// These are the only modifications to build process that are required.
compileJava {
    doFirst {
        // Directory should exists before compilation started.
        generatedSourcesDir.mkdirs()
    }
    options.compilerArgs += [ -s , generatedSourcesDir]
}

And that s it. Javac will make the rest of the job.

With Gradle 1.3 and newer (older not tested) you can use Querydsl APT like this:

configurations {
  javacApt
}
dependencies {
  javacApt  com.mysema.querydsl:querydsl-apt:3.3.0 
}
compileJava {
  options.compilerArgs <<
     -processorpath  << (configurations.compile + configurations.javacApt).asPath <<
     -processor  <<  com.mysema.query.apt.jpa.JPAAnnotationProcessor 
}

These compiler args are passed directly to javac.

To use with groovy compiler replace compileJava with compileGroovy.

To use the JPA Metamodel Generator with Gradle I m successfully using the following in my build.gradle and it works like a charm:

buildscript {
    ext {}
    repositories { // maven central & plugins.gradle.org/m2 }
    dependencies {
        // other dependencies, e.g. Spring
        classpath( gradle.plugin.at.comm_unity.gradle.plugins:jpamodelgen-plugin:1.1.1 )
    }

    apply plugin:  at.comm_unity.gradle.plugins.jpamodelgen 

    dependencies {
        compile( org.hibernate:hibernate-jpamodelgen:5.1.0.Final )
    }

    jpaModelgen {
        jpaModelgenSourcesDir = "src/main/java"
    }

    compileJava.options.compilerArgs += ["-proc:none"]
}

Within the build task, the static metamodel classes suffixed with _ are generated. Afterwards they are located in the same directory as my @Entity models are.

The Querydsl Ant example should work pretty much as is when you take all the XML out. So it ends up being something like this:

javac -sourcepath ${src} -cp ${cp} -proc:only -processor com.mysema.query.apt.jpa.JPAAnnotationProcessor -s ${generated}

src, cp and generated you will probably be able to extract from Gradle.





相关问题
Java 6 annotation processing configuration with Ant

I have a custom annotation and it s processor & processorFactory. How do I configure my Ant build file such that: The annotation processor is applied on annotated classes and generates source ...

How do I customise date/time bindings using JAXWS and APT?

Im using JAXWS 2.1.7, using some classes to run through JAXWS s apt to generate the WSDL. For dates, I use @XmlSchemaType(name="time") private Date wakeupTime; and this generates a schema ...

Eclipse compiler with APT

What is the correct way to call the Eclipse compiler with an APT processor from Java? I am using the following Maven dependency for the compiler <dependency> <groupId>org.eclipse.jdt....

Generating equals / hashcode / toString using annotation

I believe I read somewhere people generating equals / hashcode / toString methods during compile time (using APT) by identifying which fields should be part of the hash / equality test. I couldn t ...

Placeholder substitution in a Maven APT page

I am working on Maven site documentation for some related projects, and I want to create a hyperlink from one site s documentation to another sites documentation. The wrinkle is that the URL for the ...

apt warning: no annotation processor found

I am just teaching myself about web services right now and trying to run a helloWorld. I think that to setup all of the web service stuff I need to run apt. I am running it like this: apt ...

热门标签