redhat-developer / redhat-developer/vscode-java
Gradle multi-project import materializes internal build/libs jars into live JDT classpath
@snjeza arbeitet bereits daran.
Seit 21.4.2026.
- Vorherrschende Sprache
- TypeScript
- Sterne
- 2.3k
- Forks
- 546
- Ø Merge
- 20 Std. 1 Min.
- Gemergte PRs (30 T.)
- 11
Beschreibung
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
- Original Cursor thread that led to this upstream investigation: Jar files auto-created and added to classpath on Cursor startup
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/*.jardb-common/build/libs/*.jarruntime-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.jarC:\Users\<USER>\git\<REPO>\db-common\build\libs\db-common-20260420175810.jarC:\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/.classpathdid not get recreated - the workspace live
.classpathdid get recreated - the Buildship
project-preferencesfile 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/*.jarentries - 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:
GradleBuildServerProjectImporterGradleProjectImporterEclipseProjectImporter
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/*.jarentries.
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.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Bewertung
Dieses Issue wurde noch nicht bewertet.