How to perform Eclipselink Static Weaving without breaking up-to-date-checks

I’m trying to add Eclipselink Static weaving to my Java project.

I was able to do it by adding a weave task:

task weave(type: JavaExec, dependsOn: classes) {
	description = 'Performs EclipseLink static weaving of entity classes'
	group = 'build'
	def mainSS = sourceSets.main
	def source = mainSS.java.outputDir
	def resources = mainSS.output.resourcesDir
	def target = source // in-place weaving
	inputs.files source, resources
	outputs.dir target
	main 'org.eclipse.persistence.tools.weaving.jpa.StaticWeave'
	args '-persistenceinfo', source, 
		 '-classpath', configurations.runtimeClasspath.asPath, 
		 source,
		 target
	classpath configurations.runtimeClasspath
	doFirst {
		// workaround for EclipseLink bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=295031
		// copy resources into the classesDir
		copy {
			from resources
			into source
		}
	}
	doLast {
		// workaround for EclipseLink bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=295031
		// remove resources from the classesDir when finished weaving
		fileTree(dir: source).filter { it.name.equals('META-INF') || !it.name.endsWith('.class') }.each { delete it }
	}
}
[jar, test]*.dependsOn weave

So far so good, it works, but… with this approach, the up-to-date check for the classes task always fails because I’m weaving classes in-place: the outputs of the classes task (i.e.: the plain class files) are replaced with the weaved class files, so on the next run Gradle finds that the outputs of classes have changed and re-runs the task.

So I tried a different approach, using a doLast on classes and performing the weaving there:

classes.configure {
	def mainSS = sourceSets.main
	def source = mainSS.java.outputDir
	def resources = mainSS.output.resourcesDir
	def target = source // in-place weaving
	doLast {
		// workaround for EclipseLink bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=295031
		// copy resources into the classesDir
		copy {
			from resources
			into source
		}
		javaexec {
			main 'org.eclipse.persistence.tools.weaving.jpa.StaticWeave'
			args '-persistenceinfo', source,
				 '-classpath', configurations.runtimeClasspath.asPath,
				 source,
				 target
			classpath configurations.runtimeClasspath
		}
		// workaround for EclipseLink bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=295031
		// remove resources from the classesDir when finished weaving
		fileTree(dir: source).filter { it.name.equals('META-INF') || !it.name.endsWith('.class') }.each { delete it }
	}
}

This again, works, but the up-to-date check for the classes task still fails. This puzzles me, because I thought the outputs were checked after the whole classes task had finished, so after the weaving is applied in this case.

Any hint on why the second approach is not working with regards to the up-to-date check? How should I change it to make it right?

@mauromol I know it’s a bit late but it’s definitely possible to do this without breaking the up-to-date check, you just gotta make sure you wire it into the compileJava task’s last step.

For a more detailed explanation, check out my article on this: EclipseLink static weaving with Gradle.

Thanks for your hint. Indeed, the trick was to perform weaving during compileJava and not during classes. Indeed, since the up-to-date-check that fails is the one of compileJava (and not that of classes), I should have probably thought about it before.

I’m going to try this soon, thanks again!