dap-java discards module paths from resolveClasspath causing JPMS-modular projects fail to launch

Open Beginner friendly
#511 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
emacs-lisp, java
Domain
backend

Research direction

Read dap-java--populate-launch-args and the vscode.java.resolveClasspath result described in the issue. Check how the launch configuration populates :modulePaths and :classPaths, then test with a JPMS project containing module-info.java and a main class. Done means modular projects launch and debug through the module path while classpath handling still works.

Written by the indexing model from the issue text.

Description

Describe the bug

dap-java cannot launch or debug a main class that lives inside a JPMS module (any project containing a module-info.java). dap-java--populate-launch-args discards the module-path half of vscode.java.resolveClasspath's result and pins :modulePaths to an empty vector, so the class is launched in classpath mode with a module-qualified main class and dies with ClassNotFoundException.

For a class inside a declared module, vscode.java.resolveMainClass returns the module-qualified main class (e.g. kisoku.api/in.systemhalted.kisoku.api.Test), and vscode.java.resolveClasspath returns a two-element sequence [modulePaths classPaths]. But the launch populator keeps only (cl-second …) and forces :modulePaths empty:

(dap--put-if-absent :modulePaths (vector))
(dap--put-if-absent :classPaths
                    (or (cl-second (… "vscode.java.resolveClasspath" …))
                        (error "Unable to resolve classpath")))

The module paths (cl-first) are never used. The adapter then launches in classpath mode, and the Java launcher rewrites /.:

java -cp … kisoku.api/in.systemhalted.kisoku.api.Test
Error: Could not find or load main class kisoku.api.in.systemhalted.kisoku.api.Test
Caused by: java.lang.ClassNotFoundException: kisoku.api.in.systemhalted.kisoku.api.Test
Debugger failed to attach: handshake failed - connection prematurely closed

(The handshake failure is downstream — the JVM exits before jdwp attaches.)

Note

The defect is in dap-java--populate-launch-args itself and does not depend on user configuration, so it reproduces with the latest MELPA lsp-java/dap-mode and with a clean config — any project with a module-info.java triggers it.

To Reproduce

  1. Open a Maven (or Gradle) project containing a module-info.java declaring a module, e.g. module kisoku.api;, with a class in.systemhalted.kisoku.api.Test that has a public static void main(String[] args).
  2. M-x lsp to start JDT-LS; let the project import.
  3. M-x dap-debugJava Run Configuration → select the Test main class.

Expected behavior

The debug session launches via the module path (java --module-path … -m kisoku.api/in.systemhalted.kisoku.api.Test) and stops at breakpoints — the way IntelliJ and the VS Code Java debugger run modular projects.

Screenshots

N/A — the console error is reproduced above.

Logs

The failing JVM command and error are shown above. Environment: lsp-java 20260510 (MELPA), JDK 21, LSP_USE_PLISTS=true.

Root cause and proposed fix: in dap-java--populate-launch-args, resolve the classpath once and set :modulePaths from (cl-first …) when it is non-empty (keep :classPaths from (cl-second …)). With real module paths present, the bundled java-debug adapter assembles --module-path … -m module/Class itself. Happy to send a PR.

(let ((resolved-classpath
       (with-lsp-workspace (lsp-find-workspace 'jdtls)
         (lsp-send-execute-command
          "vscode.java.resolveClasspath"
          (vector main-class project-name)))))
  (-> conf
      ...
      (dap--put-if-absent :modulePaths
                          (or (cl-first resolved-classpath) (vector)))
      (dap--put-if-absent :classPaths
                          (or (cl-second resolved-classpath)
                              (error "Unable to resolve classpath")))))
Dominant language
Emacs Lisp
Stars
696
Forks
96
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from emacs-lsp/lsp-java

All issues in emacs-lsp/lsp-java

Similar issues

More Backend & API Design issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.