svaante / dape

Debug Adapter Protocol for Emacs
GNU General Public License v3.0
448 stars 25 forks source link

how to use dape with junit in java-debug #108

Closed Peter-Chou closed 1 month ago

Peter-Chou commented 3 months ago

Sorry for asking this question here. Since I can't find the solution anywhere. I made the dape works when java class has the static main method . but it breaks when i called dape and use jdtls in a test class. and i got this error message:

jsonrpc-request: jsonrpc-error: "request id=116 failed:", (jsonrpc-error-code . -32001), (jsonrpc-error-message . "Cannot invoke \"org.eclipse.jdt.core.search.SearchPattern.findIndexMatches(org.eclipse.jdt.internal.core.index.Index, org.eclipse.jdt.internal.core.search.IndexQueryRequestor, org.eclipse.jdt.core.search.SearchParticipant, org.eclipse.jdt.core.search.IJavaSearchScope, org.eclipse.core.runtime.IProgressMonitor)\" because \"pattern\" is null"), (jsonrpc-error-data :message "Cannot invoke \"org.eclipse.jdt.core.search.SearchPattern.findIndexMatches(org.eclipse.jdt.internal.core.index.Index, org.eclipse.jdt.internal.core.search.IndexQueryRequestor, org.eclipse.jdt.core.search.SearchParticipant, org.eclipse.jdt.core.search.IJavaSearchScope, org.eclipse.core.runtime.IProgressMonitor)\" because \"pattern\" is null") 

image

Peter-Chou commented 3 months ago

I tried dap-java with dap-mode, and It worked with M-x dap-java-debug-test-method https://github.com/emacs-lsp/lsp-java/blob/37c95ef7e992001250d893277acfccf4af0099b4/dap-java.el#L304

image

I'm not good at elisp, Is there a way to copy this feature?

svaante commented 2 months ago

Hey I am not that familiar with java maybe @MagielBruntink can help out.

MagielBruntink commented 2 months ago

Yes, the feature exists in the eglot-java package (on Melpa). You need to attach Dape with the Java-debug plugin once you executed a test in debug mode.

MagielBruntink commented 2 months ago

Here is my dape config for Java:


(add-to-list 'dape-configs
               `(jdtls
                 modes (java-mode java-ts-mode)
                 fn (lambda (config)
                      (with-current-buffer
                          (find-file-noselect (expand-file-name (plist-get config :program)
                                                                (project-root (project-current))))
                          (thread-first
                            config
                            (plist-put 'hostname "localhost")
                            (plist-put 'port (eglot-execute-command (eglot-current-server)
                                                                    "vscode.java.startDebugSession" nil))
                            (plist-put :projectName (project-name (project-current))))))
                 :program dape-buffer-default
                 :request "attach"
                 :hostname "localhost"
                 :port 8000)
Peter-Chou commented 2 months ago

@MagielBruntink thanks for the quick reply, I tried your config, and I got the error which fails to attach the localhost:8000 image I guess junit doesn't create the the 8000 port to attach, Is there some steps I missed?

MagielBruntink commented 2 months ago

Are you using eglot-java to launch the JVM in debug mode? By default it should be using port 8000. "Connection refused" could also mean you have a firewall blocking the connection. Try to disable that.

Peter-Chou commented 2 months ago

@MagielBruntink thank you for you help, after several attempts I finally got it worked

image

First call (eglot-java-run-test t) to start the external debug service, then use the config you give to attach the server. 👍

Peter-Chou commented 2 months ago

@MagielBruntink Hi, I still have a tiny issue here, I wish you can help me out. currently, everything works fine when using your config, just I have to put junit-platform-console-standalone dependency in pom.xml, otherwise it will break. Is there a way to directly add it to jdtls when launching dape?

image

MagielBruntink commented 2 months ago

If you launch unit tests using eglot-java it should add that junit console jar in the call to the JVM.

Peter-Chou commented 2 months ago

Let me explain how I am doing,

  1. first I called my-eglot-java-run-test-in-debug to start the deamon debug service (right not dape is not launched)

    (defun ,my-eglot-java-run-test-in-debug ()
    (interactive)
    (eglot-java-run-test t))
  2. second I called dape and type jdtls with your config to attach the service in step 1.

Following this steps, It will breaks if I remove the junit console jar.

MagielBruntink commented 2 months ago

This is the function in eglot-java I meant: https://github.com/yveszoundi/eglot-java/blob/492282d653c91b07ec10b30eb8a05cbfdc4017c7/eglot-java.el#L717

Call it with a prefix argument and it will launch the test with the JVM in debug mode. You need to configure the variable eglot-java-junit-platform-console-standalone-jar, first. And the variable for the JDTLS debug plugin jar. After the test was launched need, you can run dape and it will attach to the JVM for debugging.

Peter-Chou commented 2 months ago

Let me explain how I am doing,

  1. first I called my-eglot-java-run-test-in-debug to start the deamon debug service (right not dape is not launched)

    (defun ,my-eglot-java-run-test-in-debug ()
    (interactive)
    (eglot-java-run-test t))
  2. second I called dape and type jdtls with your config to attach the service in step 1.

Following this steps, It will breaks if I remove the junit console jar from pom.xml. Do you use the same steps?

MagielBruntink commented 2 months ago

I assume you downloaded the junit console jar and put it somewhere? And configured the variable to point to it?