Можно ли использовать jshell Java 9 для запуска кода в другой JVM?
Java 9 имеет цикл read-eval-print для Java, называемый jshell
, Я видел, как он работает в основном режиме из командной строки. Может ли оно также использоваться в удаленном процессе? Другими словами, могу ли я подключиться к другому процессу Java и ввести фрагменты кода для выполнения в этой среде выполнения? Это был бы хороший способ изменить состояние конфигурации на сервере приложений без необходимости написания инструмента администратора с пользовательским интерфейсом.
5 ответов
Ответ прост: нет способа подключить jshell к работающему процессу Java. jshell - это отдельное приложение, которое работает на собственной JVM.
Официального способа сделать это не существует.
Тем не менее, нетрудно восстановить код и запустить его на другой виртуальной машине через агент Java. Однако это не сработает так, как вы ожидаете, поскольку неясно, какой загрузчик классов должен использовать оболочка и как она должна взаимодействовать с работающей программой.
Ответ /questions/4328165/est-li-alternativnyij-sposob-zapuska-udalennogo-jvm/4328172#4328172 включает в себя хакерское решение и предложение, каким может быть чистое решение.
Часть другого ответа, предполагающая, что JShell запускает код только на своей виртуальной машине, неверна - JShell запускает отдельную JVM с транспортом через JDI по умолчанию (по крайней мере, в Linux). Но да, я не знаю официального способа, как это сделать.
Присоединение JShell - это проект, который реализует расширение JShell именно для этого. Он использует Java-агент для связи с целевой JVM.
Я не использовал его, поэтому не могу сказать, насколько хорошо он работает.
Наблюдения после быстрого осмотра
- Файл read-me выглядит профессионально.
- Код выглядит маленьким и довольно простым, как будто он давно не разрабатывается.
- В трекере ошибок нет билетов, что означает, что он мало использовался.
Пример из проекта читал меня
Запустите целевую JVM с
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=XXXhostname:XXXport
(ОбновитьXXXhostname
а такжеXXXport
при необходимости) и позвонитеnew uk.org.cinquin.attaching_jshell.ExistingVMRemoteExecutionControl()
из этой JVM до использования JShell.вызовите JShell следующим образом:
java -cp lib/attaching_jshell.jar jdk.internal.jshell.tool.JShellToolProvider --execution "attachToExistingVM:hostname(XXXhostname),port(XXXport)"
используя те же значенияXXXhostname
а такжеXXXport
как указано вышеЗапустите код в удаленной JVM следующим образом:
import uk.org.cinquin.attaching_jshell.ExistingVMRemoteExecutionControl; String s = ExistingVMRemoteExecutionControl.theGoodsForTesting
попробуйте arthas-mvel, это mvel REPL, как и jshell, и реализуйте присоединение-другого-jvm через arthas.