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

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

Java 9 有一个用于 Java 的读取-评估-打印循环,称为 jshell。我已经从命令行看到它在基本模式下工作。它也可以在远程进程中使用吗?换句话说,我可以连接到另一个 Java 进程并在 运行 时间内向 运行 输入代码片段吗?这将是更改应用程序服务器中的配置状态的好方法,而无需使用 UI.

编写管理工具

简单的答案是否定的,无法将 jshell 附加到 运行 Java 进程。 jshell 是一个在自己的 JVM 中运行的独立应用程序。

官方没有这样做的方法。

然而,通过 Java 代理重新捆绑代码并 运行 它在另一个 VM 上并不困难。然而,这不会像您预期的那样工作,因为不清楚 shell 应该使用什么 class 加载程序以及它应该如何与 运行ning 程序交互。

回答 包括 一个 hacky 解决方案和 一个建议,什么是干净的解决方案。

另一个答案中暗示 JShell 仅在其 VM 中运行代码的部分是错误的 - JShell 默认启动一个单独的 JVM,并通过 JDI 进行传输(至少在 Linux 上)。但是,是的,我不知道如何使用官方方法。

Attaching JShell 是一个为 JShell 实现扩展的项目。它使用 Java 代理与目标 JVM 通信。

我没用过所以不知道效果如何。

快速检查后的观察结果

  • 自述文件看起来很专业。
  • 代码看起来很小很简单,好像很久没开发了
  • 错误跟踪器中没有工单,这表明它没有被广泛使用。

项目自述文件中的示例

  • 使用 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=XXXhostname:XXXport 启动目标 JVM(根据需要更新 XXXhostnameXXXport)并在使用 JShell 之前从该 JVM 调用 new uk.org.cinquin.attaching_jshell.ExistingVMRemoteExecutionControl() .

  • 按如下方式调用 JShell:java -cp lib/attaching_jshell.jar jdk.internal.jshell.tool.JShellToolProvider --execution "attachToExistingVM:hostname(XXXhostname),port(XXXport)" 使用与上述相同的 XXXhostnameXXXport

  • 运行 远程 JVM 中的代码如下:

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

尝试arthas-mvel,它是一个像jshell一样的mvel REPL,通过arthas实现attaching-another-jvm。