Closed MagielBruntink closed 10 months ago
Great! I am happy. Thank you for your patience.
I am unsure how to move forward though. From https://www.gnu.org/software/emacs/manual/html_node/emacs/Copyright-Assignment.html
We can accept small changes (roughly, fewer than 15 lines) without an assignment. This is a cumulative limit (e.g., three separate 5 line patches) over all your contributions.
I don't want to keep you hanging.
The folks at FSF ask also for a disclaimer from my employer. I'll try to get that sorted this week so we can finally get this one merged :-)
@svaante I have submitted my copyright transfer to FSF and employer disclaimer.
FSF let me know that assignment has been completed.
I'm sorry that I'm asking about this so abruptly, but would it also be possible to add support for attaching the debugger from jdtls into a running JVM instance (i.e. one that has a JDWP agent active and listening on a port via the -Xrunjdwp
flag).
So basically a recipe that would ask for a port (or have the port be configurable, either works) instead of a main class, and have the :request
be "attach"
instead of "launch"
. Obviously, the part about launching the debug adapter via eglot could stay the same.
The usecase I'm mostly thinking of is having a Java app running on an application server such as Tomcat, which means that it can't necessarily be launched in the manner presented here, but has to be launched separately and then attached to later on.
Great work @MagielBruntink I will go ahead and merge this. As to @sham1 request I don't know what that entails are you or @sham1 interested in looking into how a configuration for that use case would look?
At the moment attaching to a running debugger is not a use case of mine so I will not work on it. I would like to look into running & debugging specific Java unit tests. If that overlaps it could result in an attach configuration.
@sham1 and @svaante I am changing my mind about the Java configs :-) It seems that running the JVM outside of the language server (JDTLS) is way more convenient. Eg. using Maven one can then request main classes and specific tests to be debugged, asking Dape to attach
JDTLS to the running debugger. So @sham1 's request actually pointed me in the right direction, cheers!
Here is my current init.el
config for Java:
;; ----------------------------------------
;; Java-related packages and config
;; ----------------------------------------
;; Needs JDK version 17+, installed with JAVA_HOME set and binaries on PATH.
;; Also install the following and put their executables on the PATH.
;; - JDTLS: https://github.com/eclipse-jdtls/eclipse.jdt.ls
;; - Java Debug Server: https://github.com/microsoft/java-debug
(defcustom jdtls-java-debug-plugin-jar
"/PATH/TO/java-debug/com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin-VERSION.jar"
"The path to the Java Debug Server plugin jar, see https://github.com/microsoft/java-debug"
:type '(string)
:group 'init-java)
(use-package eglot
:config
(add-to-list 'eglot-server-programs
`((java-mode java-ts-mode) .
("jdtls" ;; Try to add "-Dline.separator=\n"
:initializationOptions
(:bundles [,jdtls-java-debug-plugin-jar])))))
;; Debug Java main classes or tests using Maven, then use Dape to attach the
;; JDT LS + Java Debug Server to the running JVM.
;;
;; Main classes:
;; https://www.mojohaus.org/exec-maven-plugin/
;; $ mvnDebug -DforkCount=0 -Dexec.mainClass="Main" exec:java
;;
;; Tests:
;; https://maven.apache.org/surefire/maven-surefire-plugin/examples/debugging.html
;; https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html
;; $ mvnDebug -DforkCount=0 test
;;
;; TODO:
;; - Create convenience functions in Elisp to execute Maven commands that debug a
;; main class or test class/method at point.
;; - How to handle run/debug configurations?
(use-package dape
:if (package-installed-p 'dape)
:after eglot
:config
(add-to-list 'dape-configs
`(jdtls
modes (java-mode java-ts-mode)
hostname "localhost"
port (lambda () (eglot-execute-command (eglot-current-server)
"vscode.java.startDebugSession" nil))
:request "attach"
:hostname "localhost"
:port 8000 ;; Default port exposed by mvnDebug
:type "java")))
Thanks you so much, @sham1 and @MagielBruntink. Using that dape-config
, I can successfully connect to an external Java process (DropWizard app started with java -agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n
) :tada:
The only thing that's lacking, is the stack view. When clicking back and forth between the "tabs": Stack, Modules, Sources, I see an error when I click back on "Stack":
jsonrpc--remove: Wrong type argument: (or eieio-object cl-structure-object oclosure), nil
Hi @skybert,
Here is my personal Dape config:
(use-package dape
:if (package-installed-p 'dape)
:after eglot
:config
(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)))
I had the issue with the Stack window too, but @svaante kindly debugged and pointed out that was a problem with eglot-java
(which I use for general Java IDE features like running and debugging tests). The issue has been fixed since. If you are also an eglot-java
user (which I recommend) I think updating to the latest version will fix the problem.
This PR consolidates our earlier work to get Java debugging working.
I am in the progress of transferring copyright of this edit. However, this may be considered a "trivial" change, alleviating the need for this process?