Можно ли использовать 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.

Другие вопросы по тегам