Java 9 has a read-eval-print loop for Java, called jshell
. I've seen it work in it's basic mode, from the command line. Can it also be used in a remote process? In other words, can I connect to another Java process and enter code snippets to run within that runtime? This would be a nice way to change configuration state in an app server without having to write an admin tool with a UI.

- 36,558
- 20
- 126
- 155

- 15,024
- 17
- 92
- 165
-
2that one awesome question! – Eugene Jul 05 '17 at 19:40
-
I really like this question; because that is actually what I expected. My understanding is that *clojure* for example exactly supports this. A REPL that works in its *own* JVM, that looks kinda *lame* – GhostCat Jul 17 '17 at 14:25
-
1You can do something like this by adding the Groovy jars to your project and invoking GroovyConsole from code. Groovy has various ways to process scripts that are attached to the running JVM (The script console has access to objects passed in from your code). The scripts can just be pure java (Groovy is java but supports a relaxed syntax as well, for instance f.visible=true works the same as f.setVisible(true). I like JShell quite a bit though and I don't understand why you can't launch it from a running JVM. – Bill K Nov 25 '20 at 23:29
5 Answers
The simple answer is no, there is no way to attach jshell to a running Java process. jshell is a standalone app that runs in its own JVM.

- 3,177
- 13
- 15
-
1well yes, we all knew that, but would it be possible? in a future release or any plans to have this at all? this is what I expected from an answer... – Eugene Jul 06 '17 at 20:21
-
1Apparently, we didn't all know that, which is why the question was asked. I answered exactly what was asked. – Speakjava Jul 07 '17 at 08:41
There is no official way of doing so.
Yet, it is not to difficult to rebundle the code and run it on another VM via a Java agent. This would however not work as well as you expect it as it is unclear what class loader the shell should use and how it should interact with the running program.

- 42,759
- 13
- 108
- 192
Answer https://stackoverflow.com/a/48132747/1561345 includes a hacky solution and a suggestion, what might the clean solution be.
The part of a another answer suggesting that JShell runs the code only in its VM is wrong - JShell launches a separate JVM with transport via JDI by default (at least on Linux). But yes, I don't know of a official way how to do it.

- 71
- 1
- 4
Attaching JShell is a project that implements an extension to JShell for exactly this. It uses the Java Agent for communication with the target JVM.
I have not used it so I cannot say how well it works.
Observations after a quick inspection
- The read-me file looks professional.
- The code looks small and pretty simple, as if it hasn't been under development for a long time.
- There are no tickets in the bug tracker, which indicates that it hasn't been used much.
Example from the project read-me
Start the target JVM with
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=XXXhostname:XXXport
(updateXXXhostname
andXXXport
as appropriate) and callnew uk.org.cinquin.attaching_jshell.ExistingVMRemoteExecutionControl()
from that JVM prior to using JShell.call JShell as follows:
java -cp lib/attaching_jshell.jar jdk.internal.jshell.tool.JShellToolProvider --execution "attachToExistingVM:hostname(XXXhostname),port(XXXport)"
using the same values ofXXXhostname
andXXXport
as aboveRun code in the remote JVM like this:
import uk.org.cinquin.attaching_jshell.ExistingVMRemoteExecutionControl; String s = ExistingVMRemoteExecutionControl.theGoodsForTesting

- 11,553
- 8
- 64
- 88
try arthas-mvel, it is a mvel REPL just like jshell, and implement attaching-another-jvm via arthas.

- 164
- 1
- 7