12

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

4

5 回答 5

7

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

于 2017-07-06T12:59:04.297 回答
6

没有这样做的官方方式。

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

于 2017-07-06T22:47:26.303 回答
3

回答https://stackoverflow.com/a/48132747/1561345包括一个 hacky 解决方案和一个建议,干净的解决方案可能是什么。

另一个答案的一部分暗示 JShell 仅在其 VM 中运行代码是错误的 - JShell 默认情况下通过 JDI 启动一个单独的 JVM(至少在 Linux 上)。但是,是的,我不知道官方的方式如何做到这一点。

于 2018-01-06T23:22:14.363 回答
2

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

我没有使用它,所以我不能说它的效果如何。

快速检查后的观察

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

项目自述文件中的示例

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

  • 调用 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
    
于 2020-04-30T08:59:34.633 回答
0

试试arthas-mvel,它是一个类似于 jshell 的 mvel REPL,并通过 arthas 实现 attaching-another-jvm。

于 2021-01-24T07:05:50.957 回答