Summary
In a Gradle multi-project Java workspace, local subproject dependencies are resolved correctly as project references in the Buildship-saved model, but the live JDT/Eclipse project classpath is later materialized with internal build/libs/*.jar entries instead.
This causes local multi-module dependencies to behave like jar dependencies rather than live project/classfile dependencies, and can trigger stale or missing-library failures when those jars are rebuilt with different names.
Related discussion
I am filing here because the evidence points at the Java tooling / import / classpath materialization stack rather than a Cursor-specific layer.
Environment
- OS: Windows 11
- Java tooling: Language Support for Java by Red Hat
- Build tool: Gradle multi-project build
- Repo root:
C:\Users\<USER>\git\<REPO>
- Affected example project:
admin-tools
Observed Java server startup includes:
-Djava.import.generatesMetadataFilesAtProjectRoot=false
Affected dependency shape
The affected project depends on local Gradle subprojects via normal project dependencies, for example:
project(":server-common")
project(":db-common")
project(":runtime-common")
Expected behavior
After import/reload, local Gradle subprojects should remain project references in the live Java project model.
The live classpath should not re-add internal jars from:
server-common/build/libs/*.jar
db-common/build/libs/*.jar
runtime-common/build/libs/*.jar
Actual behavior
After restart / re-import, the live classpath for admin-tools contains internal jars again, for example:
C:\Users\<USER>\git\<REPO>\runtime-common\build\libs\runtime-common-20260420175810.jar
C:\Users\<USER>\git\<REPO>\db-common\build\libs\db-common-20260420175810.jar
C:\Users\<USER>\git\<REPO>\server-common\build\libs\server-common-20260420175810.jar
These entries come back even if removed before restart.
Confirmed findings
1. Buildship-saved model is correct
File:
C:\Users\<USER>\AppData\Roaming\Cursor\User\workspaceStorage\<WORKSPACE_ID>\redhat.java\jdt_ws\.metadata\.plugins\org.eclipse.buildship.core\project-preferences\admin-tools
What was verified:
classpath= contains project refs such as /server-common, /db-common, /runtime-common
- it contains normal external dependencies from
.gradle\caches
- it does not contain internal repo jar paths under
<REPO>/*/build/libs
This strongly suggests the Buildship-side saved model is correct.
2. Live JDT/Eclipse classpath is wrong
File:
C:\Users\<USER>\AppData\Roaming\Cursor\User\workspaceStorage\<WORKSPACE_ID>\redhat.java\jdt_ws\.metadata\.plugins\org.eclipse.core.resources\.projects\admin-tools\.classpath
Observed contents include:
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="lib" path="C:/Users/<USER>/git/<REPO>/runtime-common/build/libs/runtime-common-20260420175810.jar"/>
<classpathentry kind="lib" path="C:/Users/<USER>/git/<REPO>/db-common/build/libs/db-common-20260420175810.jar"/>
<classpathentry kind="lib" path="C:/Users/<USER>/git/<REPO>/server-common/build/libs/server-common-20260420175810.jar"/>
So the live Eclipse/JDT classpath is being materialized incorrectly after the Buildship model is already correct.
3. Repo-root .classpath is not the active source
Before restart, these were deleted:
- repo-level
admin-tools/.classpath
- workspace
org.eclipse.core.resources/.../admin-tools/.classpath
- workspace
org.eclipse.buildship.core/project-preferences/admin-tools
After restart:
- the repo-level
admin-tools/.classpath did not get recreated
- the workspace live
.classpath did get recreated
- the Buildship
project-preferences file also got recreated
This suggests the active regeneration is happening from the Java workspace/import pipeline, not from repo-root Eclipse metadata.
4. Gradle eclipse customization produced the correct model-side result
I tested targeted eclipse.classpath.file.whenMerged customization in affected subprojects to:
- remove internal
build/libs/*.jar entries
- add explicit project refs such as
/server-common, /db-common, /runtime-common
I then ran:
:admin-tools:eclipseClasspath
:db-common:eclipseClasspath
:runtime-common:eclipseClasspath
The generated .classpath outputs were correct immediately after generation, with project references present and internal local build/libs/*.jar entries absent.
This suggests the custom merge logic is not being ignored at the model-generation step.
5. Multiple importers were active in logs
Java language server logs showed multiple importers active, including:
GradleBuildServerProjectImporter
GradleProjectImporter
EclipseProjectImporter
That may be relevant if this is an importer precedence / post-processing issue.
6. Wrapper upgrade had no effect
I upgraded the project Gradle wrapper from 8.5 to 8.14.3 and re-tested.
The bad internal jar materialization still occurred, so this does not look like a simple mismatch between system Gradle and wrapper Gradle.
7. Disabling Gradle import was not a usable workaround
I also tested disabling java.import.gradle.enabled.
That severely broke import/build behavior rather than solving the classpath issue, so it does not appear to be a valid workaround.
Reproduction outline
- Open a Gradle multi-project Java workspace.
- Ensure one project depends on local subprojects via
implementation project(...).
- Let Java/Gradle import complete.
- Inspect the Buildship-saved model under
org.eclipse.buildship.core/project-preferences/....
- Inspect the live Eclipse/JDT project classpath under
org.eclipse.core.resources/.projects/.../.classpath.
- Observe that the saved model contains project refs, but the live classpath contains internal
build/libs/*.jar entries.
Impact
- breaks expected live multi-module development workflow
- makes the editor prefer built jar artifacts over local project/classfile references
- can reintroduce stale or timestamped jar references on restart
- can trigger missing-library failures when jar names change
Current hypothesis
The problem appears to happen after Buildship has already produced the correct model, during the step where org.eclipse.buildship.core.gradleclasspathcontainer is materialized into the live JDT/Eclipse project classpath.
If useful, I can provide the relevant anonymized project-preferences content, the resulting live .classpath, and the Java language server log excerpts showing the active importers.
Suggested investigation area
Please inspect how the Gradle/Buildship model is handed off to the live JDT project classpath, especially where org.eclipse.buildship.core.gradleclasspathcontainer is resolved and written into the live .classpath when local Gradle subprojects are already present as project references in the saved model.
Summary
In a Gradle multi-project Java workspace, local subproject dependencies are resolved correctly as project references in the Buildship-saved model, but the live JDT/Eclipse project classpath is later materialized with internal
build/libs/*.jarentries instead.This causes local multi-module dependencies to behave like jar dependencies rather than live project/classfile dependencies, and can trigger stale or missing-library failures when those jars are rebuilt with different names.
Related discussion
I am filing here because the evidence points at the Java tooling / import / classpath materialization stack rather than a Cursor-specific layer.
Environment
C:\Users\<USER>\git\<REPO>admin-toolsObserved Java server startup includes:
-Djava.import.generatesMetadataFilesAtProjectRoot=falseAffected dependency shape
The affected project depends on local Gradle subprojects via normal project dependencies, for example:
project(":server-common")project(":db-common")project(":runtime-common")Expected behavior
After import/reload, local Gradle subprojects should remain project references in the live Java project model.
The live classpath should not re-add internal jars from:
server-common/build/libs/*.jardb-common/build/libs/*.jarruntime-common/build/libs/*.jarActual behavior
After restart / re-import, the live classpath for
admin-toolscontains internal jars again, for example:C:\Users\<USER>\git\<REPO>\runtime-common\build\libs\runtime-common-20260420175810.jarC:\Users\<USER>\git\<REPO>\db-common\build\libs\db-common-20260420175810.jarC:\Users\<USER>\git\<REPO>\server-common\build\libs\server-common-20260420175810.jarThese entries come back even if removed before restart.
Confirmed findings
1. Buildship-saved model is correct
File:
C:\Users\<USER>\AppData\Roaming\Cursor\User\workspaceStorage\<WORKSPACE_ID>\redhat.java\jdt_ws\.metadata\.plugins\org.eclipse.buildship.core\project-preferences\admin-toolsWhat was verified:
classpath=contains project refs such as/server-common,/db-common,/runtime-common.gradle\caches<REPO>/*/build/libsThis strongly suggests the Buildship-side saved model is correct.
2. Live JDT/Eclipse classpath is wrong
File:
C:\Users\<USER>\AppData\Roaming\Cursor\User\workspaceStorage\<WORKSPACE_ID>\redhat.java\jdt_ws\.metadata\.plugins\org.eclipse.core.resources\.projects\admin-tools\.classpathObserved contents include:
So the live Eclipse/JDT classpath is being materialized incorrectly after the Buildship model is already correct.
3. Repo-root
.classpathis not the active sourceBefore restart, these were deleted:
admin-tools/.classpathorg.eclipse.core.resources/.../admin-tools/.classpathorg.eclipse.buildship.core/project-preferences/admin-toolsAfter restart:
admin-tools/.classpathdid not get recreated.classpathdid get recreatedproject-preferencesfile also got recreatedThis suggests the active regeneration is happening from the Java workspace/import pipeline, not from repo-root Eclipse metadata.
4. Gradle
eclipsecustomization produced the correct model-side resultI tested targeted
eclipse.classpath.file.whenMergedcustomization in affected subprojects to:build/libs/*.jarentries/server-common,/db-common,/runtime-commonI then ran:
:admin-tools:eclipseClasspath:db-common:eclipseClasspath:runtime-common:eclipseClasspathThe generated
.classpathoutputs were correct immediately after generation, with project references present and internal localbuild/libs/*.jarentries absent.This suggests the custom merge logic is not being ignored at the model-generation step.
5. Multiple importers were active in logs
Java language server logs showed multiple importers active, including:
GradleBuildServerProjectImporterGradleProjectImporterEclipseProjectImporterThat may be relevant if this is an importer precedence / post-processing issue.
6. Wrapper upgrade had no effect
I upgraded the project Gradle wrapper from
8.5to8.14.3and re-tested.The bad internal jar materialization still occurred, so this does not look like a simple mismatch between system Gradle and wrapper Gradle.
7. Disabling Gradle import was not a usable workaround
I also tested disabling
java.import.gradle.enabled.That severely broke import/build behavior rather than solving the classpath issue, so it does not appear to be a valid workaround.
Reproduction outline
implementation project(...).org.eclipse.buildship.core/project-preferences/....org.eclipse.core.resources/.projects/.../.classpath.build/libs/*.jarentries.Impact
Current hypothesis
The problem appears to happen after Buildship has already produced the correct model, during the step where
org.eclipse.buildship.core.gradleclasspathcontaineris materialized into the live JDT/Eclipse project classpath.If useful, I can provide the relevant anonymized
project-preferencescontent, the resulting live.classpath, and the Java language server log excerpts showing the active importers.Suggested investigation area
Please inspect how the Gradle/Buildship model is handed off to the live JDT project classpath, especially where
org.eclipse.buildship.core.gradleclasspathcontaineris resolved and written into the live.classpathwhen local Gradle subprojects are already present as project references in the saved model.