Craig Swing
Craig Swing

Reputation: 8162

How do you integrate the java annotation processor into the java plugin

I have a project that is laid out as follows:

src/
  java
  generated

src/java contains jpa entities and query classes that use the jpa metamodel classes that are generated by the hibernate metamodel annotation processor.

What is the best way to incorporate annotation processing into the java plugin?

I currently have the following task defined, but it has a task dependency on compileJava which will fail because some of the code is dependent on the classes that are generated by the annotation processor.

task processAnnotations(type: Compile) {
    genDir = new File("${projectDir}/src/generated")
    genDir.mkdirs()
    source = ['src/java']
    classpath = sourceSets.test.compileClasspath
    destinationDir = genDir
    options.compilerArgs = ["-proc:only"]
}

Upvotes: 3

Views: 5137

Answers (3)

JRomero
JRomero

Reputation: 4868

As of gradle 4.6 you simply need to define the dependency of your processor in the appropriate configuration:

dependencies {
    ...

    annotationProcessor 'org.hibernate:hibernate-jpamodelgen:4.3.7.Final'
}

Ref: https://docs.gradle.org/4.6/release-notes.html#added-annotationprocessor-configurations

Upvotes: 1

Victor Nazarov
Victor Nazarov

Reputation: 835

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: 'org.hibernate...', name: '...', version: '...')
}

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.

Upvotes: 6

Peter Niederwieser
Peter Niederwieser

Reputation: 123910

The reason why processAnnotations depends on compileJava is that you put the test compile class path on the former task's compile class path, and the test compile class path contains the compiled production code (i.e. output of compileJava).

As to how to best solve the problem at hand, you shouldn't need a separate compile task. The Java compiler can invoke annotation processors and compile their generated sources (along with the original sources) in one pass (see Annotation Processing). One thing you'll need to do is to put the annotation processor on the compile class path:

configurations {
    hibernateAnnotationProcessor
}

dependencies {
    hibernateAnnotationProcessor "org.hibernate: ..."
}

compileJava.compileClasspath += configurations.hibernateAnnotationProcessor

(You don't want to add the annotation processor to the compile configuration because then it will be considered a dependency of the production code.)

From what I can tell, this is all there is to it (assuming you are using JDK6 or higher).

Upvotes: 3

Related Questions