JDK 有一个用于远程/本地调试的内置 Java api ( com.sun.jdi. )。
要快速开始使用 api,您可以查看$JDK_DIR\demo\jpda\examples.jar中的示例。[更多详情]
由于官方的例子不是很清楚,这里是可重用的例子(灵感来自这篇博文):
VMAcquirer.java(连接管理器)
public class VMAcquirer {
public VirtualMachine connect(String host,int port) throws IOException {
String strPort = Integer.toString(port);
AttachingConnector connector = getConnector();
try {
VirtualMachine vm = connect(connector,host, strPort);
return vm;
} catch (IllegalConnectorArgumentsException e) {
throw new IllegalStateException(e);
}
}
private AttachingConnector getConnector() {
VirtualMachineManager vmManager = Bootstrap.virtualMachineManager();
for (Connector connector : vmManager.attachingConnectors()) {
if("com.sun.jdi.SocketAttach".equals(connector.name()))
return (AttachingConnector) connector;
}
throw new IllegalStateException();
}
private VirtualMachine connect(AttachingConnector connector,String host,String port)
throws IllegalConnectorArgumentsException, IOException {
Map<String, Connector.Argument> args = connector.defaultArguments();
Connector.Argument portArg = args.get("port");
portArg.setValue(port);
Connector.Argument addressArg = args.get("hostname");
addressArg.setValue(host);
return connector.attach(args);
}
}
Monitor.java(实际监控)
class Monitor {
public static void main(String[] args){
VirtualMachine vm = new VMAcquirer().connect("192.168.0.x", 2600);
System.out.println("name="+vm.name()); //Info about the remote VM
System.out.println("description="+vm.description());
EventRequestManager erm = vm.eventRequestManager();
[...] //Send request using erm instance
loopEventQueue(vm); //Start a loop to listen to the events received
}
public static void loopEventQueue(VirtualMachine vm) throws InterruptedException {
EventQueue eventQueue = vm.eventQueue();
while (true) {
EventSet eventSet = eventQueue.remove();
for (Event ev : eventSet) {
if(ev instanceof MethodEntryEvent) {
handleMethodEntryEvent(ev);
}
[...]
}
}
}
}
被监控的应用程序需要
java -Xdebug -Xrunjdwp:transport=dt_socket,address=2600,server=y,suspend=n ...
可通过 JDWP 获得的信息
跟踪方法调用和返回(可能用于分析或记录)
字段值更改
VM 信息(参见示例中的 name() 和 description())
评估表达式以执行任意代码