简体   繁体   English

可以使用 Java 9 jshell 在另一个 JVM 中运行代码吗?

[英]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 . Java 9 有一个用于 Java 的 read-eval-print 循环,称为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?换句话说,我可以连接到另一个 Java 进程并输入代码片段以在该运行时中运行吗? This would be a nice way to change configuration state in an app server without having to write an admin tool with a UI.这将是一种在应用服务器中更改配置状态的好方法,而无需编写带有 UI 的管理工具。

The simple answer is no, there is no way to attach jshell to a running Java process.简单的答案是否定的,无法将 jshell 附加到正在运行的 Java 进程。 jshell is a standalone app that runs in its own JVM. jshell 是一个独立的应用程序,它在自己的 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.然而,通过 Java 代理重新捆绑代码并在另一个 VM 上运行它并不困难。 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.然而,这不会像您期望的那样工作,因为不清楚 shell 应该使用什么类加载器以及它应该如何与正在运行的程序交互。

Answer https://stackoverflow.com/a/48132747/1561345 includes a hacky solution and a suggestion, what might the clean solution be.回答https://stackoverflow.com/a/48132747/1561345包括 一个 hacky 解决方案和 一个建议,干净的解决方案可能是什么。

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).另一个答案的一部分表明 JShell 仅在其 VM 中运行代码是错误的 - JShell 默认情况下通过 JDI 启动一个单独的 JVM(至少在 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.附加 JShell是一个为 JShell 实现扩展的项目。 It uses the Java Agent for communication with the target JVM.它使用 Java 代理与目标 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.与启动目标JVM -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=XXXhostname:XXXport (更新XXXhostnameXXXport如适用),并调用new uk.org.cinquin.attaching_jshell.ExistingVMRemoteExecutionControl()从在使用 JShell 之前的那个 JVM。

  • 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调用 JShell 如下: java -cp lib/attaching_jshell.jar jdk.internal.jshell.tool.JShellToolProvider --execution "attachToExistingVM:hostname(XXXhostname),port(XXXport)"使用与上面相同的XXXhostnameXXXport

  • Run code in the remote JVM like this:在远程 JVM 中运行代码,如下所示:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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