Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Cannot run JUnit 5 test via lsp-jt-browser

Open
#419 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
emacs-lisp, java
Domain
testing, tooling

Research direction

Reproduce the failure from lsp-jt-browser using the supplied pom.xml, Main, and MainTest, then trace the workspace/executeCommand request for vscode.java.test.runtime.classpath and the related lsp-jt--start-test entry point. Compare the LSP logs with the working mvn test result; done means selecting Plus Test runs successfully without the delegateCommandHandler or listp errors.

Written by the indexing model from the issue text.

Description

Describe the bug

Cannot run JUnit 5 test in my project via lsp-jt-browser. When I select the test in "Test Explorer" and press x — then I got an error:

lsp-jt--start-test: Wrong type argument: listp, #("LSP :: `workspace/executeCommand' with `vscode.java.test.runtime.classpath' failed.

(error \"No delegateCommandHandler for vscode.java.test.runtime.classpath\")" 0 3 (face error))

I tried to remove .classpath, .project, .settings/ from my project sources, remove all lsp-related directories in ~/.emacs.d and remove all lsp-related packages itself to upload it from melpa-stable again. Problem was not solved.

Package versions:

  • lsp-mode-8.0.0
  • lsp-java-3.1
  • lsp-treemacs-0.4
  • lsp-ui-8.0.1
  • dap-mode-0.7

Simular bug, but related to DAP with lsp-java: #411

To Reproduce

Create project with next pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.9.1</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.junit</groupId>
            <artifactId>junit-bom</artifactId>
            <version>${junit.version}</version>
            <type>pom</type>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>3.0.0-M8</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>

Create simple method to test in main class:

package org.example;

public class Main
{
    public static void main(String[] args)
    {
        System.out.println("Hello world!");
    }

    public int plus(int a, int b)
    {
        return a + b;
    }
}

Write test class with one test method:

package org.example;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;


public class MainTest
{
    @Test
    @DisplayName("Plus test")
    public void plusTest()
    {
        Assertions.assertEquals(4, new Main().plus(1, 3));
    }
}

(Optionally) Test what tests running in IDEA or via Maven:

% mvn test                                                                                                                                                    [01:38:26] drag0n@gentoo
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------------< org.example:test >--------------------------
[INFO] Building test 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ test ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ test ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/drag0n/test2/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ test ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/drag0n/test2/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ test ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/drag0n/test2/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:3.0.0-M8:test (default-test) @ test ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.example.MainTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.05 s - in org.example.MainTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.050 s
[INFO] Finished at: 2023-01-27T01:45:00+03:00
[INFO] ------------------------------------------------------------------------

Open project in Emacs, import it when LSP asks about root project folder (select ~/test2, because project in ~/test2). After that run M-x lsp-jt-browser, expand MainTest node and select Plus Test. Press x to run this test and receive the error:

lsp-jt--start-test: Wrong type argument: listp, #("LSP :: `workspace/executeCommand' with `vscode.java.test.runtime.classpath' failed.

(error \"No delegateCommandHandler for vscode.java.test.runtime.classpath\")" 0 3 (face error))

Expected behavior

Test is running without that error.

Screenshots

Screenshot of error: https://pasteboard.co/sy6FBpI3TXkU.png

Logs

Debugger entered--Lisp error: (error "No delegateCommandHandler for vscode.java.test.run...")
  signal(error ("No delegateCommandHandler for vscode.java.test.run..."))
  error("No delegateCommandHandler for vscode.java.test.run...")
  (cond ((eq resp-result :finished) nil) (resp-result resp-result) ((lsp-json-error\? resp-error) (error (lsp:json-error-message resp-error))) ((lsp-json-error\? (cl-first resp-error)) (error (lsp:json-error-message (cl-first resp-error)))))
  (progn (lsp-request-async method params #'(lambda (res) (setq resp-result (or res :finished)) (throw 'lsp-done '_)) :error-handler #'(lambda (err) (setq resp-error err) (throw 'lsp-done '_)) :no-merge no-merge :mode 'detached :cancel-token :sync-request) (while (not (or resp-error resp-result)) (catch 'lsp-done (accept-process-output nil (- expected-time send-time))) (setq send-time (time-to-seconds (current-time))) (if (< expected-time send-time) (progn (error "Timeout while waiting for response.  Method: %s" method)))) (setq done\? t) (cond ((eq resp-result :finished) nil) (resp-result resp-result) ((lsp-json-error\? resp-error) (error (lsp:json-error-message resp-error))) ((lsp-json-error\? (cl-first resp-error)) (error (lsp:json-error-message (cl-first resp-error))))))
  (unwind-protect (progn (lsp-request-async method params #'(lambda (res) (setq resp-result (or res :finished)) (throw 'lsp-done '_)) :error-handler #'(lambda (err) (setq resp-error err) (throw 'lsp-done '_)) :no-merge no-merge :mode 'detached :cancel-token :sync-request) (while (not (or resp-error resp-result)) (catch 'lsp-done (accept-process-output nil (- expected-time send-time))) (setq send-time (time-to-seconds (current-time))) (if (< expected-time send-time) (progn (error "Timeout while waiting for response.  Method: %s" method)))) (setq done\? t) (cond ((eq resp-result :finished) nil) (resp-result resp-result) ((lsp-json-error\? resp-error) (error (lsp:json-error-message resp-error))) ((lsp-json-error\? (cl-first resp-error)) (error (lsp:json-error-message (cl-first resp-error)))))) (if done\? nil (lsp-cancel-request-by-token :sync-request)))
  (let* ((send-time (time-to-seconds (current-time))) (expected-time (+ send-time lsp-response-timeout)) resp-result resp-error done\?) (unwind-protect (progn (lsp-request-async method params #'(lambda (res) (setq resp-result (or res :finished)) (throw 'lsp-done '_)) :error-handler #'(lambda (err) (setq resp-error err) (throw 'lsp-done '_)) :no-merge no-merge :mode 'detached :cancel-token :sync-request) (while (not (or resp-error resp-result)) (catch 'lsp-done (accept-process-output nil (- expected-time send-time))) (setq send-time (time-to-seconds (current-time))) (if (< expected-time send-time) (progn (error "Timeout while waiting for response.  Method: %s" method)))) (setq done\? t) (cond ((eq resp-result :finished) nil) (resp-result resp-result) ((lsp-json-error\? resp-error) (error (lsp:json-error-message resp-error))) ((lsp-json-error\? (cl-first resp-error)) (error (lsp:json-error-message (cl-first resp-error)))))) (if done\? nil (lsp-cancel-request-by-token :sync-request))))
  (if no-wait (lsp-notify method params) (let* ((send-time (time-to-seconds (current-time))) (expected-time (+ send-time lsp-response-timeout)) resp-result resp-error done\?) (unwind-protect (progn (lsp-request-async method params #'(lambda (res) (setq resp-result ...) (throw ... ...)) :error-handler #'(lambda (err) (setq resp-error err) (throw ... ...)) :no-merge no-merge :mode 'detached :cancel-token :sync-request) (while (not (or resp-error resp-result)) (catch 'lsp-done (accept-process-output nil (- expected-time send-time))) (setq send-time (time-to-seconds (current-time))) (if (< expected-time send-time) (progn (error "Timeout while waiting for response.  Method: %s" method)))) (setq done\? t) (cond ((eq resp-result :finished) nil) (resp-result resp-result) ((lsp-json-error\? resp-error) (error (lsp:json-error-message resp-error))) ((lsp-json-error\? (cl-first resp-error)) (error (lsp:json-error-message ...))))) (if done\? nil (lsp-cancel-request-by-token :sync-request)))))
  (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '(:no-wait :no-merge :allow-other-keys)) (setq --cl-keys-- (cdr (cdr --cl-keys--)))) ((car (cdr (memq ... --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:no-wait :no-merge..." (car --cl-keys--)))))) (if no-wait (lsp-notify method params) (let* ((send-time (time-to-seconds (current-time))) (expected-time (+ send-time lsp-response-timeout)) resp-result resp-error done\?) (unwind-protect (progn (lsp-request-async method params #'(lambda ... ... ...) :error-handler #'(lambda ... ... ...) :no-merge no-merge :mode 'detached :cancel-token :sync-request) (while (not (or resp-error resp-result)) (catch 'lsp-done (accept-process-output nil ...)) (setq send-time (time-to-seconds ...)) (if (< expected-time send-time) (progn ...))) (setq done\? t) (cond ((eq resp-result :finished) nil) (resp-result resp-result) ((lsp-json-error\? resp-error) (error ...)) ((lsp-json-error\? ...) (error ...)))) (if done\? nil (lsp-cancel-request-by-token :sync-request))))))
  (let* ((no-wait (car (cdr (plist-member --cl-rest-- ':no-wait)))) (no-merge (car (cdr (plist-member --cl-rest-- ':no-merge))))) (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '...) (setq --cl-keys-- (cdr ...))) ((car (cdr ...)) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:no-wait :no-merge..." (car --cl-keys--)))))) (if no-wait (lsp-notify method params) (let* ((send-time (time-to-seconds (current-time))) (expected-time (+ send-time lsp-response-timeout)) resp-result resp-error done\?) (unwind-protect (progn (lsp-request-async method params #'... :error-handler #'... :no-merge no-merge :mode 'detached :cancel-token :sync-request) (while (not ...) (catch ... ...) (setq send-time ...) (if ... ...)) (setq done\? t) (cond (... nil) (resp-result resp-result) (... ...) (... ...))) (if done\? nil (lsp-cancel-request-by-token :sync-request)))))))
  lsp-request("workspace/executeCommand" (:command "vscode.java.test.runtime.classpath" :arguments [["/home/drag0n/test2/src/test/java/org/example/MainT..."]]))
  (let ((params (if args (list :command command :arguments args) (list :command command)))) (lsp-request "workspace/executeCommand" params))
  (condition-case err (let ((params (if args (list :command command :arguments args) (list :command command)))) (lsp-request "workspace/executeCommand" params)) ((debug error) (lsp--error "`workspace/executeCommand' with `%s' failed.\n\n%S" command err)))
  lsp-workspace-command-execute("vscode.java.test.runtime.classpath" [["/home/drag0n/test2/src/test/java/org/example/MainT..."]])
  lsp-send-execute-command("vscode.java.test.runtime.classpath" [["/home/drag0n/test2/src/test/java/org/example/MainT..."]])
  lsp-jt--start-test(#<hash-table equal 7/65 0x156d8e06c349> nil)
  lsp-jt--start-from-browser(nil)
  lsp-jt-run()
  funcall-interactively(lsp-jt-run)
  call-interactively(lsp-jt-run nil nil)
  command-execute(lsp-jt-run)

M-x lsp-print-io answers [No match] :-(

Dominant language
Emacs Lisp
Stars
696
Forks
97
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

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 Testing & QA issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.