简体   繁体   中英

Can the Java 9 jshell be used to run code in another JVM?

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.

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.

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.

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.

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 (update XXXhostname and XXXport as appropriate) and call new 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 of XXXhostname and XXXport as above

  • Run code in the remote JVM like this:

     import uk.org.cinquin.attaching_jshell.ExistingVMRemoteExecutionControl; String s = ExistingVMRemoteExecutionControl.theGoodsForTesting

试试arthas-mvel ,它是一个和 jshell 一样的 mvel REPL,并通过 arthas 实现 attach-another-jvm。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM