如何设置JDI启动连接器?

所以我正在尝试自己进入JDI。 通过首先使用VM命令启动调试对象,我已经成功将调试器应用程序挂接到我的debugee程序中:

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

然后启动我的调试器,通过使用附加连接器建立连接:

 VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); AttachingConnector ac = vmm.attachingConnectors().get(0); Map 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 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 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。 但是我猜我的调试器是自己做的还是什么? 我担心我没有真正掌握所有这些方法调用的function。

所以我的问题:为什么我的调试对象程序没有启动?

如上所示,我确实将“main”参数设置为:

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

我的调试器应用程序在同一个包(p)中。 那应该是正确的吗? 但显然我在这里做错了。 有任何想法吗?

谢谢!

这可能是因为您没有处理子进程stdin / stdout流。 我在我的JDI脚本项目中有一个VMLauncher实用程序类来处理这个问题。 相关代码是:

 public VirtualMachine safeStart() throws IOException, IllegalConnectorArgumentsException, VMStartException { VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); LaunchingConnector connector = vmm.defaultConnector(); Map 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; } 

您是否在LaunchingConnector中设置了类路径?

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