#java #debugging #jdi
#java #отладка #jdi
Вопрос:
В настоящее время я изучаю Java JDI и пытаюсь запустить виртуальную машину, на которой запущена моя нужная программа, и установить соединение с запущенной виртуальной машиной, на которой запущена нужная программа.
Для этого я использую соединитель запуска («com.sun.jdi.CommandLineLaunch»).
Я даю соединителю запуска следующие аргументы:
LaunchingConnector connector = findConnecter();
Map args = connector.defaultArguments();
//Main Arguments
Connector.Argument mainArgs = (Connector.Argument)args.get("main");
mainArgs.setValue("Main2");
//Options Arguments
Connector.Argument options = (Connector.Argument)args.get("options");
options.setValue("-cp .");
Затем запустите соединитель с VirtualMachine vm = connector.launch(args);
помощью . Однако, когда я распечатываю список классов, загруженных с использованием следующего фрагмента кода:
List<ReferenceType> classes = vm.allClasses();
for (int i = 0; i<classes.size(); i ){
System.out.println(classes.get(i).name());
}
Класс Main2 отсутствует в списке.
Я предполагаю, что это проблема с путем к классу, но не смог заставить это работать. Main2.class файл находится в том же каталоге, что и класс, в котором находится приведенный выше код.
Кто-нибудь знает, в чем проблема?
Ответ №1:
Основной класс не загружается изначально из-за приостановки работы виртуальной машины непосредственно перед ее загрузкой.
Чтобы получать уведомления о загружаемых классах, вам необходимо создать ClassPrepareRequest и включить его. Затем обработайте запущенную виртуальную машину ‘EventQueue’ по мере поступления событий. Некоторые события приводят к приостановке работы виртуальной машины, поэтому после этого необходимо вызвать vm.resume().
Пример обработки:
while (true) {
//Waits forever for the next available event. Pauses here until something is available.
EventSet eventSet = eventQ.remove();
for(Event event: eventSet){
if(event instanceof ClassPrepareEvent){
ClassPrepareEvent classPrepareEvent = (ClassPrepareEvent)event;
ReferenceType refType = classPrepareEvent.referenceType();
System.out.println("---" refType.name() " loaded.");
}
vm.resume()
}
}