Запуск агента Java после запуска программы

Можно ли вставить javaagent после запуска виртуальной машины из той же виртуальной машины?

Допустим, например, у нас есть агент в jar myagent.jar с соответствующей настройкой метаданных и уже реализованным методом agentmain. Теперь пользовательская программа вызывает API-вызов, который должен привести к вставке агента, чтобы он мог переопределить классы.

Можно ли это сделать и как?

3 ответа

https://web.archive.org/web/20141014195801/http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/ содержит отличный пример того, как писать агент, а также, как начать один на лету.

Да, вам просто нужно передать идентификатор процесса JVM в VirtualMachine.attach(String pid) метод и загрузить агент банку. VirtualMachine класс доступен в файле JDK_HOME/lib/tools.jar. Вот пример того, как я активирую агент во время выполнения:

public static void attachGivenAgentToThisVM(String pathToAgentJar) {
  try {                                                                               
    String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();                                                   
    String pid = nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@'));                                                   
    VirtualMachine vm = VirtualMachine.attach(pid);                                                                            
    vm.loadAgent(pathToAgentJar, "");
    vm.detach();   
  } catch (Exception e) {
    e.printStackTrace();
  }
}                                                                                                            

Вы должны быть в состоянии сделать это в Java 6, см. Главу документации пакета "Запуск агентов после запуска виртуальной машины"

Редактировать: Возможно, это было возможно в Java 5 уже, и просто Javadocs не упомянул об этом явно

Столкнувшись с той же проблемой, я нашел гораздо более полное решение из библиотеки ByteBuddy.

ByteBuddy тщательно пытается динамически загрузить свой java-агент:

Устанавливает агент на работающую в данный момент виртуальную машину Java. К сожалению, это не всегда работает. Установка агента Java во время выполнения поддерживается для:

  • JVM версии 9+: для Java VM как минимум версии 9 API вложений был перемещен в модуль, и установка среды выполнения возможна, если для Byte Buddy доступен модуль {@code jdk.attach}, который обычно доступен только для виртуальных машин. поставляется с JDK.
  • OpenJDK / Oracle JDK / IBM J9 версий 8-: установка HotSpot возможна только в комплекте с JDK и требует {@code tools.jar} в комплекте с виртуальной машиной, который обычно доступен только для JDK-версий JVM.
  • При запуске Linux и включении дополнительной зависимости junixsocket-native-common Byte Buddy имитирует соединение сокета Unix для подключения к целевой виртуальной машине.
  • Другие вопросы по тегам