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
- 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).
M-x lsp to start JDT-LS; let the project import.
M-x dap-debug → Java 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")))))
Describe the bug
dap-javacannot launch or debug amainclass that lives inside a JPMS module (any project containing amodule-info.java).dap-java--populate-launch-argsdiscards the module-path half ofvscode.java.resolveClasspath's result and pins:modulePathsto an empty vector, so the class is launched in classpath mode with a module-qualified main class and dies withClassNotFoundException.For a class inside a declared module,
vscode.java.resolveMainClassreturns the module-qualified main class (e.g.kisoku.api/in.systemhalted.kisoku.api.Test), andvscode.java.resolveClasspathreturns a two-element sequence[modulePaths classPaths]. But the launch populator keeps only(cl-second …)and forces:modulePathsempty:The module paths (
cl-first) are never used. The adapter then launches in classpath mode, and the Java launcher rewrites/→.:(The handshake failure is downstream — the JVM exits before jdwp attaches.)
Note
The defect is in
dap-java--populate-launch-argsitself and does not depend on user configuration, so it reproduces with the latest MELPAlsp-java/dap-modeand with a clean config — any project with amodule-info.javatriggers it.To Reproduce
module-info.javadeclaring a module, e.g.module kisoku.api;, with a classin.systemhalted.kisoku.api.Testthat has apublic static void main(String[] args).M-x lspto start JDT-LS; let the project import.M-x dap-debug→ Java Run Configuration → select theTestmain 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-java20260510 (MELPA), JDK 21,LSP_USE_PLISTS=true.Root cause and proposed fix: in
dap-java--populate-launch-args, resolve the classpath once and set:modulePathsfrom(cl-first …)when it is non-empty (keep:classPathsfrom(cl-second …)). With real module paths present, the bundled java-debug adapter assembles--module-path … -m module/Classitself. Happy to send a PR.