Skip to content

Fix task order between compileJava and processResources. - #7323

Merged
bjhargrave merged 1 commit into
bndtools:masterfrom
ejjcase:6896-gradle-task-order
Jul 20, 2026
Merged

bjhargrave merged 1 commit into
bndtools:masterfrom
ejjcase:6896-gradle-task-order

Conversation

@ejjcase

@ejjcase ejjcase commented Jul 20, 2026 •

Copy link
Copy Markdown
Contributor

Fix for #6896 in the Gradle case only.

Both these tasks have the same output directory. If compileJava runs first, which can sometimes happen when cached state is reused, then processResources clears out the output directory when it runs, deleting all the classes. But if processResources runs first, compileJava happily writes classes into the same directory tree without deleting the resources.

I've done the same thing for the test source set.

I noticed that when the source sets have extensions for other languages, BndPlugin adds the outputs of processResources as inputs to the extra AbstractCompile tasks. This was added recently in #7313. I'm not sure whether this was done to enforce a task ordering dependency or if the inputs are actually needed for some reason. I know that they're not needed for Java compilation, so I opted for a simple ordering between the tasks.

I tried to write a test:

  • Start with a Bnd workspace containing a bundle that has a Java class and a resource
  • In the bundle's Gradle configuration, add a doLast block to the jar task to verify that the jar contained a class
  • Repeatedly run the tasks clean and jar to see if the check ever failed

Unfortunately I couldn't get the build to ever fail. I think it's because the Gradle Test Kit doesn't use a Gradle daemon in the usual way, so there's no opportunity for the cache to get into a state where it starts changing the task order.

@chrisrueger

Copy link
Copy Markdown
Contributor

Thanks for the PR.

I noticed that when the source sets have extensions for other languages, BndPlugin adds the outputs of processResources as inputs to the extra AbstractCompile tasks. This was added recently in #7313. I'm not sure whether this was done to enforce a task ordering dependency or if the inputs are actually needed for some reason.

I think the answer is in the Example of comment (see the "Expected" headline): #7306 (comment)

I know that they're not needed for Java compilation

I am not so sure, given the problem of #7306 (and if I understand your sentence correctly).
If I understand #7306 correctly compileJava needs result of processResource (because procesResource adds .class files which should be visible for compilation.

Maybe @bjhargrave and @jhanders34 have an opinion.

Comment thread gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BndPlugin.java Outdated
@ejjcase

ejjcase commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the PR.

I noticed that when the source sets have extensions for other languages, BndPlugin adds the outputs of processResources as inputs to the extra AbstractCompile tasks. This was added recently in #7313. I'm not sure whether this was done to enforce a task ordering dependency or if the inputs are actually needed for some reason.

I think the answer is in the Example of comment (see the "Expected" headline): #7306 (comment)

I know that they're not needed for Java compilation

I am not so sure, given the problem of #7306 (and if I understand your sentence correctly). If I understand #7306 correctly compileJava needs result of processResource (because procesResource adds .class files which should be visible for compilation.

My understanding of the example you linked is that the bundle mostly contains classes included from an external jar, but wants to replace one class with a locally compiled version. The test needs the local version to appear before the included one on the classpath, but it wouldn't normally get that, because Gradle normally runs tests against the output of classes and processResources (i.e. two separate trees of files) instead of against the built jar. This is why prepending the jar to the test compile classpath is a valid workaround.

There aren't any compile tasks in the example where the compiler needs to see any resources belonging to the same source set. Even if there were, you could just put them on the buildpath/testpath.

@chrisrueger

Copy link
Copy Markdown
Contributor

the bundle mostly contains classes included from an external jar, but wants to replace one class with a locally compiled version. The test needs the local version to appear before the included one on the classpath

You are right. Forget my remark. I misinterpreted.

@bjhargrave
bjhargrave force-pushed the 6896-gradle-task-order branch from ccbf425 to 24b3b12 Compare July 20, 2026 18:32
Both these tasks have the same output directory. If compileJava runs first, which can sometimes happen when cached state is reused, then processResources clears out the output directory when it runs, deleting all the classes. But if processResources runs first, compileJava happily writes classes into the same directory tree without deleting the resources.

Signed-off-by: Eleanor Joslin <[email protected]>
Signed-off-by: BJ Hargrave <[email protected]>
@bjhargrave
bjhargrave force-pushed the 6896-gradle-task-order branch from 24b3b12 to 968b11e Compare July 20, 2026 18:45
@bjhargrave
bjhargrave merged commit 30fbb0a into bndtools:master Jul 20, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants