Whenever I quit emacs or run nrepl-quit I get an orphaned JVM process remaining.
Attached should be an image showing the emacs process tree after running nrepl-jack-in.
I also tested with CIDER 20131018.1553 from a fresh .emacs.d with just cider/clojure-mode and had the same problem.

This Stack Overflow comment seems to indicate that the bug has been around since at least April.
I'll investigate the problem. Might be something Windows related, though - since I don't think I've seen orphaned processes on OSX and Linux.
This has to be something Windows specific, since I cannot reproduce it on OSX.
I'd be happy to help you debug the problem if you don't have a Windows install handy.
It's probably worth noting that I don't get this problem with any other programs that spawn a copy of the JVM. For example Leiningen spawns the same process structure but both java.exe processes are terminated when it exits.
You should debug what happens in cider--close-buffer when it's passed the connection buffer. You might instrument that function with C-u C-M-x and just invoke cider-quit. delete-process should normally kill the underlying Java process, but for some reason it seems that this is not happening on Windows.
I'm not familiar enough with nrepl.el/CIDER or elisp to know what I should be looking for.
It seems the parent java.exe process _is_ getting killed, just not the child for some reason.
@drguildo Might be an Emacs bug then, since delete-process is a core Emacs function. You may get more info regarding this if you post a question on the emacs-devel mailing list.
I filed an Emacs bug and this is what one of the developers had to say:
Emacs on Windows can only monitor and kill its immediate subprocesses, it cannot monitor, let alone kill, any of their descendant processes, because it has no idea about them. And the OS doesn't automatically kill all the processes in the subprocess tree, and there's no way to send a signal to them all, as on Posix platforms. If killing the immediate child process doesn't cause some of its children to exit or abort, then those grandchildren will be left orphaned.
Why doesn't the child java.exe exit when it parent does? Can you arrange for that to happen? Failing that, I don't think there's a solution to this problem, sorry.
So I was correct when I assumed this was an Windows-related "bug". Since I don't use Windows, I don't know what we can do at this point. I guess we need some explicit tracking of processes there, but someone else will have to implement it.
If I run (System/exit 0) in the REPL, all Java processes are killed. Would it be possible to do this or something similar in cider--close-buffer?
I guess we can. I wonder if there are even simpler solutions to this problem.
IMHO assuming that the OS will kill a child process if we exit is not simple, it is sloppy. My vote is for explicitly shutting down any owned VM on shutdown of the host, and considering anything created via jack-in as owned.
@noisesmith Perhaps you're right. On the other hand I don't recall ever seeing someone tracking explicitly child processed in Emacs Lisp code. I'll look into that.
@drguildo A friend of mine (who's a crazy Windows hacker) checked that claim on emacs-devel and created a patch that debunks it - see the patch he provided here.
I don't really have any expertise here, but let me add links to a couple of issues I've seen that might be relevant. There's a similar problem with orphaned JVMs in Gorilla REPL on Windows:
https://github.com/JonyEpsilon/lein-gorilla/issues/4
@jtcb investigated a bit, and has good reason to suspect it's a leiningen problem:
Closing this as there's not much we can do about it.
I do not really understand why this issue was closed. It is a big problem, and it is not solved in Emacs 24.5 for Windows.
I currently use this workaround in .emacs
(defun my-kill-java ()
(interactive)
(cider-interactive-eval "(System/exit 0)")
)
(defun turn-on-my-clojure-commands ()
:
(define-key clojure-mode-map (kbd "C-c q") 'my-kill-java)
)
(add-hook 'clojure-mode-hook 'turn-on-my-clojure-commands)
It's closed because it's not a cider issue, it's an Emacs (or lein) issue.
Ok, but maybe we should at least tell users about a workaround? The hanging java-processes will kill the machine, and a generic command like "pskill java" will also kill databases like datomic and cassandra.
How do I set the command for the repl too, i.e. what is the clojure-repl-mode-map called?
Ok, but maybe we should at least tell users about a workaround? The hanging java-processes will kill the machine, and a generic command like "pskill java" will also kill databases like datomic and cassandra.
I'd normally just inspect all Java processes and kill the relevant ones. As repl restarts are uncommon I don't think this is major issue anyways.
How do I set the command for the repl too, i.e. what is the clojure-repl-mode-map called?
cider-repl-mode-map.
I think doing (shutdown-agents) lets the jvm quit by itself on windows. I think it is the windows JVM that starts some non-server thread that then blocks the normal exit. I wish I could recall what project I read this information in (maybe Nightcode, maybe ring-jetty, not sure).
I have solved it by calling (System/exit 0) from within the repl.
I added a command to .emacs
(defun my-kill-java ()
(interactive)
(cider-interactive-eval "(System/exit 0)")
)
(define-key cider-repl-mode-map (kbd "C-c C-q") 'my-kill-java)
If I just call (shutdown-agents) , pskill still finds two java-processes to kill. This doesn't happen when I use (System/exit 0)
I've fussed with the code a bit. The solutions above using cider-interactive-eval block and sometimes leave orphaned cider interaction buffers. The following code has made my repl shutdown nicely reliable:
(defun my-kill-java ()
(interactive)
(cider-nrepl-send-unhandled-request
(list "op" "eval"
"code" "(do
(.start
(Thread.
(fn []
(Thread/sleep 5000)
(shutdown-agents)
(System/exit 0))))
nil)"))
(cider-quit 'QUIT-ALL))
Supposedly @benedekfazekas fixed this recently with https://github.com/benedekfazekas/cider/commit/7cd9c7032f6c65869d5a1ba1e4292f4375585cf2
I saw that, but did not think to test it. I will test and confirm. Thank you!
The fix looks good to me. All the cases that used to leave a vm running, now do not.
Most helpful comment
I do not really understand why this issue was closed. It is a big problem, and it is not solved in Emacs 24.5 for Windows.
I currently use this workaround in .emacs