2014-02-09 6 views
4

Так что я пытаюсь работать в JDI. Я уже был успешно закреплять мой отладчик приложение в моей debugee программе, первый запуск отлаживаемый с VM команды:Как установить соединительный разъем 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); 

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

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); 

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

// 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. Но я думаю, что мой отладчик делает все это для себя или чего-то еще? Боюсь, я действительно не понял, что делают все эти вызовы.

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

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

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

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

Спасибо!

ответ

1

Возможно, это связано с тем, что вы не обрабатываете потоки 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; 
} 
0

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

env.get("options").setValue("-cp " + 
    "/my-project/target/classes:" + 
    "/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/tools.jar:" + 
    ""); 
Смежные вопросы