Java JDI CommandLineLaunch не загружает нужный класс

#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()
             }
}