Я использую API-интерфейс attach для загрузки агента JVMTI во время выполнения. Я хотел бы разгрузить агент JVMTI, когда моя программа будет завершена без завершения JVM, в который загружен агент. Согласно этой документации нет способ сделать это из API-интерфейса attach. Существуют ли какие-либо другие способы заставить агента выгружать его самостоятельно через API Java или из агента JVMTI?
Выгрузка агента JVMTI во время выполнения?
Ответ 1
Ответ 2
Вам необходимо загрузить программу JVMTI программно:
// attach to target VM
VirtualMachine vm = VirtualMachine.attach("2177");
// get system properties in target VM
Properties props = vm.getSystemProperties();
// construct path to management agent
String home = props.getProperty("java.home");
String agent = home + File.separator + "lib" + File.separator
+ "your-agent-example.jar";
// load agent into target VM
vm.loadAgent(agent, "com.sun.management.jmxremote.port=5000");
// detach
vm.detach();
см. doc здесь
После этого вы должны использовать другой классLoad, чем значение по умолчанию:
Вы должны установить системное свойство "java.system.class.loader" как имя своего пользовательского загрузчика классов для вашей целевой JVM.
см. doc здесь
"Java builtin Class loaders всегда проверяет, загружен ли класс перед загрузкой. Поэтому перезагрузка класса невозможна с помощью встроенных загрузчиков классов Java. Чтобы перезагрузить класс, вам придется реализовать свой собственный класс ClassLoader.
В вашем случае вам нужно реализовать ClassLoader, у которого ClassLoader.getSystemClassLoader() имеет родительский элемент.
"Даже с пользовательским подклассом ClassLoader у вас есть проблема. Каждый загруженный класс должен быть связан. Это делается с использованием метода ClassLoader.resolve(). Этот метод является окончательным и, следовательно, не может быть переопределен в вашем подклассе ClassLoader. Метод resolve() не позволит любому экземпляру ClassLoader дважды связать один и тот же класс. Поэтому каждый раз, когда вы хотите перезагрузить класс, вы должны использовать новый экземпляр вашего подкласса ClassLoader. Это не невозможно, но необходимо знать при проектировании для перезагрузки класса. "