Как настроить коннектор запуска JDI?

Поэтому я пытаюсь работать в JDI. Я уже успешно подключил свое приложение-отладчик к моей отлаживаемой программе, сначала запустив отлаживаемую программу с помощью команд виртуальной машины:

-agentlib:jdwp=transport=dt_socket,server=y,address=8000

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

VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
AttachingConnector ac = vmm.attachingConnectors().get(0);
Map<String, Connector.Argument> env = ac.defaultArguments();
env.get("port").setValue("8000");
env.get("hostname").setValue("localhost");
VirtualMachine vm = ac.attach(env);

Но теперь я хочу, чтобы мое приложение-отладчик запускало саму отлаживаемую программу. Я понимаю, что в этом случае нужно использовать пусковой разъем. Итак, я попробовал это:

VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
LaunchingConnector lc = vmm.launchingConnectors().get(0);
Map<String, Connector.Argument> env = lc.defaultArguments();
env.get("main").setValue("p.DebugDummy");
env.get("suspend").setValue("true");
env.get("home").setValue("C:/Program Files/Java/jdk1.7.0_51");
VirtualMachine vm = lc.launch(env);

Однако, когда я запускаю это приложение, моя отлаживаемая программа не запускается. Я не получаю никаких исключений или чего-то еще, несмотря на то, что у меня есть куча кода, следующего за кодом, показанным выше; такие вещи, как:

    // A single implementor of this interface exists in a particuar VM
    EventRequestManager mgr = vm.eventRequestManager();

    // suspend VM
    vm.suspend();

    // lookup main thread
    ThreadReference mainThread = null;
    List<ThreadReference> threads = vm.allThreads();
    for (ThreadReference thread : threads) {
        if ("main".equals(thread.name())) {
            mainThread = thread;
            break;
        }
    }

    // resume 
    vm.resume();
    mainThread.resume();

    // There is one instance of EventQueue assigned to a particular
    // VirtualMachine.
    EventQueue eventQueue = vm.eventQueue();

    // Waits for start event.
    WAIT_FOR_START: do {
        EventSet eventSet = eventQueue.remove();
        EventIterator eventIterator = eventSet.eventIterator();
        while (eventIterator.hasNext()) {
            Event event = eventIterator.next();
            if (event instanceof VMStartEvent) {
                System.out.println("VMStartEvent.");
                break WAIT_FOR_START;
            }
        }
    } while (true);

    System.out.println("GO...");

Все нормально проходит?! У меня нет исключений и все sysouts (GO... и т.д.). Я нахожу это довольно странным — очевидно, он находит основной поток и VMStartEvent. Но я предполагаю, что мой отладчик делает все это сам с собой или что-то в этом роде? Боюсь, я не совсем понял, что делают все эти вызовы методов.

Итак, мой вопрос: почему моя отлаживаемая программа не запускается?

Как вы можете видеть выше, я установил «основной» аргумент:

env.get("main").setValue("p.DebugDummy");

Мое приложение-отладчик находится в том же пакете (p). Так должно быть правильно? Но очевидно, что я делаю что-то не так здесь. Любые идеи?

Благодарю вас!


person user3237736    schedule 09.02.2014    source источник


Ответы (2)


Вероятно, это связано с тем, что вы не обрабатываете потоки подпроцесса stdin/stdout. У меня есть VMLauncher служебный класс в моем проекте сценариев JDI, который обрабатывает это; соответствующий код:

public VirtualMachine safeStart()
    throws IOException,
           IllegalConnectorArgumentsException,
           VMStartException
{
    VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
    LaunchingConnector connector = vmm.defaultConnector();
    Map<String, Argument> cArgs = connector.defaultArguments();
    cArgs.get("options").setValue(options);
    cArgs.get("main").setValue(main);
    final VirtualMachine vm = connector.launch(cArgs);

    final Thread outThread = redirect("Subproc stdout",
                                      vm.process().getInputStream(),
                                      out);
    final Thread errThread = redirect("Subproc stderr",
                                      vm.process().getErrorStream(),
                                      err);
    if(killOnShutdown) {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                outThread.interrupt();
                errThread.interrupt();
                vm.process().destroy();
            }
        });
    }

    return vm;
}

private Thread redirect(String name, InputStream in, OutputStream out) {
    Thread t = new StreamRedirectThread(name, in, out);
    t.setDaemon(true);
    t.start();
    return t;
}
person jfager    schedule 20.03.2014

Вы установили свой путь к классам в LaunchingConnector?

env.get("options").setValue("-cp " +
  "/my-project/target/classes:" +
  "/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/tools.jar:" +
  "");
person Victor Grazi    schedule 21.02.2016