Skip to content

Resolve linked source folders when building the classpath - #1984

Open
sorteam wants to merge 1 commit into
spring-projects:mainfrom
sorteam:resolve-linked-source-folders
Open

Resolve linked source folders when building the classpath#1984
sorteam wants to merge 1 commit into
spring-projects:mainfrom
sorteam:resolve-linked-source-folders

Conversation

@sorteam

@sorteam sorteam commented Sep 4, 2026

Copy link
Copy Markdown

ClasspathUtil.resolveWorkspacePath turns a classpath entry into a filesystem location by
appending the entry path to the project location:

IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0));
IPath projectRoot = project.getLocation();
return projectRoot.append(path.removeFirstSegments(1));

That is correct only while a source folder is a real directory inside the project. When the source
folder is a linked resource, the computed directory does not exist, createSourceCPE hands that
path to the client anyway, and SpringIndexerJava.getFiles() - Files.walk over
IClasspathUtil.getProjectJavaSourceFolders(...) - walks nothing. The project then contributes no
symbols at all: no beans, no request mappings, not even handwritten ones.

Reproduction

A project whose .project declares

<linkedResources>
  <link><name>main</name><type>2</type><location>/path/to/sources</location></link>
</linkedResources>

and whose .classpath has <classpathentry kind="src" path="main"/>, with no main directory in
the project folder. The CPE that reaches the language server is <project location>/main, which does
not exist.

Projects shaped like this are not exotic:

  • the invisible project the Java language server creates for a plain folder links the workspace
    folder in under ProjectUtils.WORKSPACE_LINK;
  • project importers contributed by other extensions keep the project metadata in the language
    server's storage and link each source root - which is how I ran into this.

Measured on such a workspace of 116 generated projects: 228 of 244 source classpath entries pointed
at directories that do not exist, and the Spring index was empty for every project.

Fix

Ask the resource model first, and keep the existing arithmetic as a fallback for paths it does not
know about. Eight lines, no behaviour change for projects whose source folders are real directories.

Verification

I compiled the modified class against the jars shipped in vmware.vscode-spring-boot 2.3.0 together
with the jdt.ls plugins from redhat.java, and confirmed the emitted bytecode calls findMember
before the fallback. I have not run the project's own build or test suite (Tycho/target
platform), so please treat the change as needing your CI.

ClasspathUtil turned a classpath entry into a filesystem location by
appending the entry path to the project location. That is wrong whenever
the source folder is a linked resource: the directory it computes does
not exist, SpringIndexerJava.getFiles() walks nothing, and the project
contributes no symbols at all - no beans, no request mappings, not even
handwritten ones.

Projects shaped that way are not exotic. The invisible project the Java
language server creates for a plain folder links the workspace folder
in, and project importers contributed by other extensions keep the
project metadata outside the repository and link every source root.

Ask the resource model first and fall back to the previous arithmetic
for paths it does not know about.

Signed-off-by: Artem <sorteam@users.noreply.github.com>
@martinlippert martinlippert added this to the 5.5.0.RELEASE milestone Sep 4, 2026
@martinlippert martinlippert self-assigned this Sep 4, 2026
@martinlippert martinlippert added type: bug for: eclipse something that is specific for Eclipse for: vscode something that is specific for VSCode labels Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

for: eclipse something that is specific for Eclipse for: vscode something that is specific for VSCode type: bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants