Skip to content

cannot recognize Maven projects with multiple submodules #1041

Closed
redhat-developer/vscode-java
#4473

Description

When a Maven project contains multiple submodules, the JAVA PROJECTS view cannot correctly recognize and display the project structure.

As shown in the screenshot below:

Image

Activity

  1. github-actions commented on Jul 19, 2026

    @github-actions

    Hi Satan (@interstellar-pixel), I'm an AI Support assistant here to help with your issue. While the team reviews your request, I wanted to provide some possible tips and documentation that might help you in the meantime.

    Workarounds

    • Manually add each sub‐module to the Java Projects view: click the + in the Java Projects pane (“Add Folder to Java Projects”) and select the module folder.
    • Verify Java > Dependency: Auto Refresh is enabled so updates in pom.xml get picked up.

    Known issue (no fix yet)

    Other high-confidence reference

    Other references with low confidence

    The team will respond to your issue shortly. I hope these suggestions are helpful in the meantime. If this comment helped you, please give it a 👍. If the suggestion was not helpful or incorrect, please give it a 👎. Your feedback helps us improve!

  2. Mayankshrey438 commented on Jul 19, 2026

    @Mayankshrey438

    Hi! I'd like to work on this issue. Could you please assign it to me? I'll investigate the root cause and submit a PR if it's within the scope of the extension. Thank you!

  3. gazingabyss commented on Jul 20, 2026

    @gazingabyss

    Hi! I'd like to work on this issue. Could you please assign it to me? I'll investigate the root cause and submit a PR if it's within the scope of the extension. Thank you!

    I think I've identified the problem. The JAVA_PROJECTS view works normally when I open the same project locally or access it through an SSH connection to the remote server. However, as soon as I connect to the Docker container, the issue mentioned above occurs.

  4. wenytang-ms commented on Jul 22, 2026

    @wenytang-ms
    Contributor

    Hi Satan (@interstellar-pixel), Satan (@gazingabyss), Mayank Shrey (@Mayankshrey438) — thanks a lot for the report and for digging into this together! 🙏

    The finding that it only reproduces inside a Docker container (while opening locally and over SSH remote both work fine) is a really useful clue and helps narrow down the root cause a lot.

    As this is an open-source project, we warmly welcome contributions from the community. If any of you would like to investigate further and open a PR with a fix, we'd be very happy to review and help get it merged. To make it easier to track down, a minimal reproducible example would be great — e.g. a small multi-module Maven project plus the Dev Container / docker configuration you're using.

    Thanks again for helping improve the extension! 🎉

  5. wenytang-ms commented on Jul 22, 2026

    @wenytang-ms
    Contributor

    Thanks for the detailed reports! The fact that it works locally and over SSH remote but breaks only in a Docker container is a great clue — it rules out a generic Maven multi-module bug (and it's not Linux-specific, since SSH remote is Linux too).

    The Java Projects view is just a thin client: it renders whatever jdtls returns from java.project.list, and the multi-module detection happens server-side. So a container-only failure most likely comes from the environment — e.g. the workspace being a symlink/bind-mount under /workspaces/... (jdtls canonicalizes paths on import), or an empty ~/.m2 / restricted network causing parent-POM resolution to fail.

    To help us narrow it down, from inside the container could you share:

    • The Java output channel log around Importing Maven project(s)
    • readlink -f /workspaces/<your-project> (is the workspace a symlink?)
    • Whether ~/.m2/repository is populated and the container has network access

    A minimal repro (small multi-module project + your devcontainer.json/Dockerfile) would help us reproduce it directly. Thanks! 🙏

  6. interstellar-pixel commented on Jul 27, 2026

    @interstellar-pixel
    Author

    Hi wenyt (@wenytang-ms), below is the relevant information I have provided.

    The Java output channel log around Importing Maven project(s)

    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.755
    !MESSAGE Non-Static Commands: [vscode.java.test.jacoco.getCoverageDetail, vscode.java.test.findJavaProjects, vscode.java.test.findTestPackagesAndTypes, vscode.java.test.findTestTypesAndMethods, vscode.java.test.resolvePath, vscode.java.test.findTestLocation, vscode.java.test.get.testpath, vscode.java.test.findDirectTestChildrenForClass, vscode.java.test.navigateToTestOrTarget, vscode.java.test.junit.argument, vscode.java.test.generateTests]
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.756
    !MESSAGE Static Commands: []
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.756
    !MESSAGE Non-Static Commands: [java.maven.initializeSearcher, java.maven.searchArtifact, java.maven.addDependency, java.maven.controlContext]
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.756
    !MESSAGE Static Commands: []
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.756
    !MESSAGE Non-Static Commands: [java.gradle.delegateTest]
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.757
    !MESSAGE Static Commands: []
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.757
    !MESSAGE Non-Static Commands: [vscode.java.checkProjectSettings, vscode.java.isOnClasspath, vscode.java.fetchUsageData, vscode.java.validateLaunchConfig, vscode.java.resolveInlineVariables, vscode.java.resolveClassFilters, vscode.java.resolveMainMethod, vscode.java.resolveClasspath, vscode.java.resolveBuildFiles, vscode.java.resolveMainClass, vscode.java.updateDebugSettings, vscode.java.resolveSourceUri, vscode.java.fetchPlatformSettings, vscode.java.buildWorkspace, vscode.java.startDebugSession, vscode.java.inferLaunchCommandLength, vscode.java.resolveElementAtSelection, vscode.java.resolveJavaExecutable]
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.757
    !MESSAGE Static Commands: []
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.757
    !MESSAGE Non-Static Commands: [java.project.refreshLib, java.project.checkImportStatus, java.project.list, java.project.generateJar, java.project.getFileImports, java.project.getMainClasses, java.project.getImportClassContent, java.getPackageData, java.project.getDependencies, java.resolvePath]
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.772
    !MESSAGE RepositoryRegistryUpdateJob finished 1ms
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.786
    !MESSAGE >> initialized
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.806
    !MESSAGE Importers: GradleBuildServerProjectImporter, GradleProjectImporter, MavenProjectImporter, EclipseProjectImporter, InvisibleProjectImporter
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.837
    !MESSAGE Importing Maven project(s)
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.919
    !MESSAGE Progressive import: reporting 1 new project(s)
    
    !ENTRY org.eclipse.jdt.ls.core 4 0 2026-07-27 10:11:32.921
    !MESSAGE Initialization failed 
    !STACK 0
    java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters: /workspace/JAVA_Projects/RuoYi/doc/������������������������.docx
    	at java.base/sun.nio.fs.UnixPath.encode(Unknown Source)
    	at java.base/sun.nio.fs.UnixPath.<init>(Unknown Source)
    	at java.base/sun.nio.fs.UnixFileSystem.getPath(Unknown Source)
    	at java.base/java.nio.file.Path.of(Unknown Source)
    	at java.base/java.nio.file.Paths.get(Unknown Source)
    	at org.eclipse.core.internal.filesystem.local.nio.PosixHandler.fetchFileInfo(PosixHandler.java:41)
    	at org.eclipse.core.internal.filesystem.local.LocalFileNativesManager.fetchFileInfo(LocalFileNativesManager.java:83)
    	at org.eclipse.core.internal.filesystem.local.LocalFile.fetchInfo(LocalFile.java:230)
    	at org.eclipse.core.filesystem.provider.FileStore.fetchInfo(FileStore.java:236)
    	at org.eclipse.core.filesystem.provider.FileStore.childInfos(FileStore.java:69)
    	at org.eclipse.core.internal.localstore.UnifiedTree.getLocalList(UnifiedTree.java:390)
    	at org.eclipse.core.internal.localstore.UnifiedTree.addChildren(UnifiedTree.java:160)
    	at org.eclipse.core.internal.localstore.UnifiedTree.addNodeChildrenToQueue(UnifiedTree.java:275)
    	at org.eclipse.core.internal.localstore.UnifiedTree.accept(UnifiedTree.java:129)
    	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refreshResource(FileSystemResourceManager.java:1096)
    	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refresh(FileSystemResourceManager.java:1079)
    	at org.eclipse.core.internal.resources.Resource.refreshLocal(Resource.java:1683)
    	at org.eclipse.core.internal.resources.Project.open(Project.java:1189)
    	at org.eclipse.core.internal.resources.Project.open(Project.java:1245)
    	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.create(ProjectConfigurationManager.java:847)
    	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.lambda$1(ProjectConfigurationManager.java:153)
    	at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:462)
    	at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:342)
    	at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:281)
    	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.importProjects(ProjectConfigurationManager.java:139)
    	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.importProjects(ProjectConfigurationManager.java:130)
    	at org.eclipse.jdt.ls.core.internal.managers.MavenProjectImporter.importToWorkspace(MavenProjectImporter.java:242)
    	at org.eclipse.jdt.ls.core.internal.managers.ProjectsManager.importProjects(ProjectsManager.java:169)
    	at org.eclipse.jdt.ls.core.internal.managers.ProjectsManager.initializeProjects(ProjectsManager.java:126)
    	at org.eclipse.jdt.ls.core.internal.handlers.InitHandler$1.runInWorkspace(InitHandler.java:264)
    	at org.eclipse.core.internal.resources.InternalWorkspaceJob.run(InternalWorkspaceJob.java:43)
    	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.949
    !MESSAGE >> initialization job finished
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.996
    !MESSAGE >> build jobs finished
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.997
    !MESSAGE >> registerWatchers'
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:32.999
    !MESSAGE >> registerFeature 'workspace/didChangeWatchedFiles'
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:55.752
    !MESSAGE >> shutdown
    
    !ENTRY org.eclipse.jdt.ls.core 1 0 2026-07-27 10:11:55.753
    !MESSAGE >> exit
    

    readlink -f /workspaces/<your-project> (is the workspace a symlink?)

    The directory is directly mounted from the host machine when the container is started.

    ubuntu@name:/workspace/JAVA_Projects/RuoYi$ readlink -f ../RuoYi/
    /workspace/JAVA_Projects/RuoYi

    Whether ~/.m2/repository is populated and the container has network access

    Yes, the project can be compiled and run correctly, and the container has Internet access

    The example repository url: https://github.com/yangzongzhuan/RuoYi.git

  7. wenytang-ms commented on Jul 27, 2026

    @wenytang-ms
    Contributor

    Thanks Satan (@interstellar-pixel) — that log was exactly what we needed, it pins the root cause down completely.

    This is not a multi-module problem, and not a bug in the Java Projects view. It is a file-name encoding problem inside the container.

    Root cause

    The decisive lines in your log:

    !MESSAGE Progressive import: reporting 1 new project(s)
    !MESSAGE Initialization failed
    java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters:
      /workspace/JAVA_Projects/RuoYi/doc/????????????????????????.docx
    

    Your repository contains doc/若依环境使用手册.docx. That name is 8 CJK characters = 24 UTF-8 bytes, and the log shows exactly 24 replacement characters — one per byte. That is the signature of the JVM decoding the file name with a single-byte ASCII charset.

    The JVM derives that charset (sun.jnu.encoding) from the process locale at startup. A Docker container starts with LANG=C/POSIX by default, so sun.jnu.encoding becomes ANSI_X3.4-1968 (ASCII). The file name is decoded into U+FFFD characters, and Paths.get() can no longer encode it back — hence the InvalidPathException.

    That exception is raised while opening the root project (Project.open → refreshLocal walks doc/), and it aborts the entire workspace initialization right after reporting 1 new project(s). So the six modules — ruoyi-admin, ruoyi-common, ruoyi-framework, ruoyi-generator, ruoyi-quartz, ruoyi-system — are never imported. That is exactly what your screenshot shows.

    It also explains why it works locally and over SSH remote: both of those sessions already have a UTF-8 locale.

    Workaround

    Give the container a UTF-8 locale.

    In your Dockerfile:

    ENV LANG=C.UTF-8
    ENV LC_ALL=C.UTF-8

    or in devcontainer.json:

    "containerEnv": {
      "LANG": "C.UTF-8",
      "LC_ALL": "C.UTF-8"
    }

    Then rebuild the container and reload the window. On older base images where C.UTF-8 is not available, use en_US.UTF-8 and make sure it is generated first (apt-get install -y locales && locale-gen en_US.UTF-8).

    ⚠️ What does not work: adding -Dsun.jnu.encoding=UTF-8 or -Dfile.encoding=UTF-8 to java.jdt.ls.vmargs. The JVM overwrites sun.jnu.encoding from the OS locale during startup and silently ignores the value passed on the command line (verified on JDK 21). The process locale is the only lever.

    We will fix to vscode-java. once new fix bits release, will notify.

    Thanks again to Satan (@gazingabyss) for narrowing it down to "only inside Docker" — that observation is what made this findable, and to Satan (@interstellar-pixel) for the reproducible sample.

  8. interstellar-pixel commented on Jul 27, 2026

    @interstellar-pixel
    Author

    Thanks @interstellar-pixel — that log was exactly what we needed, it pins the root cause down completely.

    This is not a multi-module problem, and not a bug in the Java Projects view. It is a file-name encoding problem inside the container.

    Root cause

    The decisive lines in your log:

    !MESSAGE Progressive import: reporting 1 new project(s)
    !MESSAGE Initialization failed
    java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters:
      /workspace/JAVA_Projects/RuoYi/doc/????????????????????????.docx
    

    Your repository contains doc/若依环境使用手册.docx. That name is 8 CJK characters = 24 UTF-8 bytes, and the log shows exactly 24 replacement characters — one per byte. That is the signature of the JVM decoding the file name with a single-byte ASCII charset.

    The JVM derives that charset (sun.jnu.encoding) from the process locale at startup. A Docker container starts with LANG=C/POSIX by default, so sun.jnu.encoding becomes ANSI_X3.4-1968 (ASCII). The file name is decoded into U+FFFD characters, and Paths.get() can no longer encode it back — hence the InvalidPathException.

    That exception is raised while opening the root project (Project.open → refreshLocal walks doc/), and it aborts the entire workspace initialization right after reporting 1 new project(s). So the six modules — ruoyi-admin, ruoyi-common, ruoyi-framework, ruoyi-generator, ruoyi-quartz, ruoyi-system — are never imported. That is exactly what your screenshot shows.

    It also explains why it works locally and over SSH remote: both of those sessions already have a UTF-8 locale.

    Workaround

    Give the container a UTF-8 locale.

    In your Dockerfile:

    ENV LANG=C.UTF-8
    ENV LC_ALL=C.UTF-8
    or in devcontainer.json:

    "containerEnv": {
    "LANG": "C.UTF-8",
    "LC_ALL": "C.UTF-8"
    }
    Then rebuild the container and reload the window. On older base images where C.UTF-8 is not available, use en_US.UTF-8 and make sure it is generated first (apt-get install -y locales && locale-gen en_US.UTF-8).

    ⚠️ What does not work: adding -Dsun.jnu.encoding=UTF-8 or -Dfile.encoding=UTF-8 to java.jdt.ls.vmargs. The JVM overwrites sun.jnu.encoding from the OS locale during startup and silently ignores the value passed on the command line (verified on JDK 21). The process locale is the only lever.

    We will fix to vscode-java. once new fix bits release, will notify.

    Thanks again to @gazingabyss for narrowing it down to "only inside Docker" — that observation is what made this findable, and to @interstellar-pixel for the reproducible sample.

    Thank you wenyt (@wenytang-ms) very much for your patience and guidance throughout this process. I applied the temporary workaround you provided, rebuilt the container, and the issue has now been resolved.

    I sincerely appreciate your support and would also like to express my gratitude to you and the Java extension team for your great work and contributions.


    Then now I have another question regarding the Java Projects view.

    When the Hide Non-Java Resources option is enabled, all non-Java resources are hidden from the Java Projects view (including files such as application.yml and .xml files.). However, when switching to Show Non-Java Resources, the view also shows an empty src/main folder and a duplicate empty target folder, which appear to be unnecessary.

    Would it be possible to refine the Java Projects view rendering logic to avoid displaying these redundant directories and provide a cleaner project structure view?

    Image
  9. wenytang-ms commented on Jul 27, 2026

    @wenytang-ms
    Contributor

    Glad to hear the workaround resolved it, and thanks again for sticking with this — the log and the sample you provided are what made the root cause findable.

    The permanent fix is now open as redhat-developer/vscode-java#4473. Once it ships, the language server will be started with a UTF-8 locale automatically when the inherited one cannot represent non-ASCII file names, so no container change will be needed. I will follow up here when it is released.

    On your second point about the empty src/main and duplicate target folders under Show Non-Java Resources — that makes sense to me and is worth addressing, but it is unrelated to the encoding problem tracked here. Could you open it as a separate feature request in this repository? Please include the screenshot you posted above and the project layout, and we will follow up there.

    Keeping this issue scoped to the file-name encoding problem so it can be closed once the fix ships.

  10. interstellar-pixel commented on Jul 27, 2026

    @interstellar-pixel
    Author

    wenyt (@wenytang-ms) Thank you for your response. I will create a new issue to further track and discuss the duplicate folder display issue mentioned above.

  11. wenytang-ms commented on Aug 24, 2026

    @wenytang-ms
    Contributor

    Hi Satan (@interstellar-pixel) we shipped the new pre-release bits for this issue, please upgrade to 0.27.2026082200 to verify. thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions