Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 13, 2025

Bnd workspace projects write both compiled classes and processed resources to the same output directory. Without explicit task ordering, Gradle can execute compileJava and processResources in parallel, allowing resource processing to overwrite compiled classes.

Changes

  • Added mustRunAfter constraints in BndPlugin.java:
    • processResources.mustRunAfter(compileJava) for main source set
    • processTestResources.mustRunAfter(compileTestJava) for test source set

This enforces execution order when both tasks run, preventing the race condition while preserving existing build semantics.

TaskProvider<Task> processResourcesTask = tasks.named(sourceSet.getProcessResourcesTaskName());
generateInputAction.ifPresent(processResourcesTask::configure);
// Since both compileJava and processResources write to the same destination directory,
// we must ensure processResources runs after compileJava to prevent resources from
// overwriting compiled classes (issue #6896)
processResourcesTask.configure(t -> t.mustRunAfter(compileTask));

Scope

This fix addresses the race condition in Gradle builds only (affecting target/gradle/classes). The issue has been reported to also occur in Eclipse builds (affecting target/classes), which use a different build system (Eclipse JDT) and are not addressed by this PR. Investigation into the Eclipse-specific issue is ongoing.

Partially addresses #6896 (Gradle builds)

Original prompt

This section details on the original issue you should resolve

<issue_title>Bnd sometimes leaves classes out of bundles</issue_title>
<issue_description>This is a very odd one where I can see the symptoms but can't reproduce it consistently (thank goodness). I thought about reporting it earlier but decided to try investigating it myself first. However, that hasn't led anywhere.

I have a Bnd workspace containing many bundle projects. Their sources are laid out in the traditional Eclipse way with java classes and other resources mixed together under src/. I'm not sure if that's important.

They are all set up with these properties:

tool-modifier:          ${if;${is;${driver};gradle};/gradle}
target-dir:             target
src:                    src
testsrc:                unitTests/src
bin:                    ${target-dir}${tool-modifier}/classes
testbin:                ${target-dir}${tool-modifier}/testClasses

I sometimes use Eclipse, and sometimes Gradle. I've seen this bug in both.

Sometimes when I'm rebuilding the workspace, the build will stop with compile errors. When I investigate, I see that one of the earlier bundles has resources in it but no classes. If it has an activator, there's also a warning that the activator was not found in the bundle.

target/classes/ or target/gradle/classes/ (depending on the driver) only contains resources, but I can see that compilation took place, because there are usually some compiler warnings.

If I delete target/classes/ (in Eclipse) or simply try the build again (in Gradle) it will usually build the bundle properly, but then I'll get the same problem with a different bundle.

This usually continues until I perform the right combination of cleaning the workspace, stopping the Gradle daemon, restarting the IDE … I'm not sure. Then I might not see the problem again for a few days, but it has always come back.

CI builds use Gradle but I don't think I've seen this bug in one of those; I thought I had, then I found another problem with similar symptoms and worked around it. I suppose that since every CI build starts with a clean checkout, there isn't time for the problem to occur.

I can also consistently make the bug go away in Gradle by disabling all the processResources tasks. Then there are no resources in the bundles unless they are placed there by an -includeresource, but the classes are all present.

My hypothesis is that the classes are indeed being written into the correct folder, but then they are somehow overwritten when the resources are copied in. I understand that Gradle or Eclipse, not Bnd, is handling the resources in this case. But I haven't seen a bug like this when I wasn't using Bnd, so I think Bnd must have something to do with it.

I tried writing a Python script that monitored the filesystem for new files and made them all read only, in the hopes of causing an error that would help me work out what was going on. It didn't work — either permissions don't work the way I hoped they would or something was making the files writable again before deleting them. However, I did see the script crash because a file whose permissions it was trying to change had already been deleted by the time it got round to doing that.

Gradle is using Bnd 7.1.0 with Gradle 8.14.3, but Eclipse is using a 7.2.0-SNAPSHOT build. I updated my Bndtools snapshot today, but haven't been doing the kind of work that would make the bug show up. I definitely saw it in an older snapshot from September.

I suppose I should try separating the Java sources from the resource files, and perhaps keep the Java sources under src/ but put the other files somewhere where Gradle wouldn't look for them. Then use -includeresource to put them all in so that Bnd has full control of the process. (Would that make them bypass the classes folder?) But that's an invasive change I would rather not make at the moment.</issue_description>

<agent_instructions>Analyze the issue #6896 and the source code. If you think something needs to be fixed,please provide a PR.
Relevant code might be under /gradle-plugins </agent_instructions>

Comments on the Issue (you are @copilot in this section)

@chrisrueger Hmm my first reflex was to point you to https://bnd.bndtools.org/chapters/150-build.html#avoiding-target-dir-conflicts-between-different-build-tools and https://bnd.discourse.group/t/stop-gradle-from-stepping-on-eclipses-long-toes/295/11

but it looks you are already using the driver to use different folders for each build tool.

But it sounds like two tools are stepping on each other's toes.

I suppose I should try separating the Java sources from the resource files, and perhaps keep the Java sources under src/ but put the other files somewhere where Gradle wouldn'...


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits November 13, 2025 15:23
- Add mustRunAfter constraint from processResources to compileJava
- Add mustRunAfter constraint from processTestResources to compileTestJava
- Prevents resources from overwriting compiled classes when both write to same directory
- Fixes issue #6896

Co-authored-by: chrisrueger <[email protected]>
Copilot AI changed the title [WIP] Fix issue with missing classes in Bnd bundles Fix race condition causing classes to be omitted from bundles Nov 13, 2025
Copilot AI requested a review from chrisrueger November 13, 2025 15:30
Copilot finished work on behalf of chrisrueger November 13, 2025 15:30
@chrisrueger
Copy link
Contributor

@copilot Now there is a comment:

The changes I have made seem to have worked around the bug in Gradle. But when I closed IntelliJ and started Eclipse, I immediately saw the bug again.

target/gradle still exists and is populated, but Eclipse shouldn't be using it. target did not contain anything other than gradle when Eclipse started.

Gradle is now not running at all, and even if it was, it wouldn't be pointing at the output directories Eclipse uses.

I am running Eclipse 2025-09 with Bndtools 7.2.0.202511121342-SNAPSHOT.

Copy link
Contributor Author

Copilot AI commented Nov 13, 2025

@copilot Now there is a comment:

The changes I have made seem to have worked around the bug in Gradle. But when I closed IntelliJ and started Eclipse, I immediately saw the bug again....

The Gradle fix I implemented only addresses task ordering within Gradle builds (using target/gradle/classes). The Eclipse issue appears to be independent since Eclipse uses target/classes directly.

Could you provide more details about what you're seeing in Eclipse?

  • Do you see resources in target/classes but no .class files?
  • Or are both present but the bundle JAR only contains resources?
  • Does cleaning the project (Project → Clean) help temporarily?

The Eclipse builder delegates compilation to JDT (Java Development Tools), and I need to understand if the issue is with Eclipse's builders or with how bnd processes the output directory.

Copilot AI changed the title Fix race condition causing classes to be omitted from bundles Fix race condition causing classes to be omitted from bundles in Gradle builds Nov 13, 2025
Copilot finished work on behalf of chrisrueger November 13, 2025 15:43
@chrisrueger
Copy link
Contributor

Closing, as this was just for brainstorming and getting ideas.

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.

Bnd sometimes leaves classes out of bundles

2 participants