How to compile generated sources after the compile already ran?


(Jochen Mader) #1

I am currently trying to get QueryDSL running with Scala in Gradle. To generate the required Q-objects I built the following task: task gen << {

def exporter = new GenericExporter()

exporter.setKeywords(Keywords.JPA);

exporter.setTargetFolder(new java.io.File("${buildDir}/generated/scala"))

exporter.setSerializerClass(ScalaEntitySerializer.class)

exporter.setTypeMappingsClass(ScalaTypeMappings.class)

exporter.setEntityAnnotation(Entity.class);

exporter.setEmbeddableAnnotation(Embeddable.class);

exporter.setEmbeddedAnnotation(Embedded.class);

exporter.setSupertypeAnnotation(MappedSuperclass.class);

exporter.setSkipAnnotation(Transient.class);

exporter.setCreateScalaSources(true)

exporter.export(“de”) }

classes.dependsOn(gen)

Problem is that it has to run after things have already been built because GenericExporter is analyzing the generated byte code. How can I tell Gradle to build the Scala-Files the task will generate?


(Peter Niederwieser) #2

You’ll have to add a task of type ScalaCompile and configure it as necessary.


(Jochen Mader) #3

Thanks for the quick reply. Got it working during my lunch-break :slight_smile: I got it working using: task compileGenerated(type: ScalaCompile) {

source = file("${buildDir}/generated/scala")

destinationDir = new File("${buildDir}/classes/generated")

scalaCompileOptions.incrementalOptions.analysisFile = new File("${buildDir}/tmp/scala/compilerAnalysis/compileCustomScala.analysis")

classpath = buildscript.configurations.classpath }

compileGenerated.dependsOn(gen) classes.dependsOn(compileGenerated)

The final problem I have is now the order of tasks. I expected compileGenerated to be executed right before classes doing ‘gradle clean build’. Instead I got the following order: :entity:clean :entity:gen UP-TO-DATE :entity:compileGenerated UP-TO-DATE :entity:compileJava UP-TO-DATE :entity:compileScala :entity:processResources :entity:classes :entity:jar :entity:assemble :entity:compileTestJava UP-TO-DATE :entity:compileTestScala UP-TO-DATE :entity:processTestResources UP-TO-DATE :entity:testClasses UP-TO-DATE :entity:test :entity:check :entity:build

So compileGenerated gets executed before compileScala. How can I get my compileGenerated-task to execute at the right moment?


(Jochen Mader) #4

Got it, but is it the right thing to do?: task compileGenerated(type: ScalaCompile) {

outputs.upToDateWhen {

return false

}

source = file("${buildDir}/generated/scala")

destinationDir = new File("${buildDir}/classes/generated")

scalaCompileOptions.incrementalOptions.analysisFile = new File("${buildDir}/tmp/scala/compilerAnalysis/compileCustomScala.analysis")

classpath = buildscript.configurations.classpath }

compileGenerated.dependsOn(gen) jar.dependsOn(compileGenerated)


(Peter Niederwieser) #5

You are missing a task dependency. I don’t know exactly how your tasks build on each other, but maybe it’s ‘gen.dependsOn(compileScala)’.


(Peter Niederwieser) #6

Not sure what exactly your question is about. The need for ‘upToDateWhen { false }’ is an indication that something might be configured incorrectly. Also you probably want to include the generated code in the Jar.


(Jochen Mader) #7

You gave me the correct line :slight_smile: After inserting it I was also able to remove upToDateWhen { false }. Thanks a lot!