package net.ranides.demo.debugger; import com.sun.jdi.VMDisconnectedException; import com.sun.jdi.event.LocatableEvent; import com.sun.jdi.request.BreakpointRequest; import java.util.Optional; public class AppDebugger { private static final String EXAMPLE = "net.ranides.demo.debugger.AppObservable$ExampleObject@19"; public static void main(String[] args) { try (var debugger = new SimpleDebugger()) { var example = debugger.connect("localhost", "5151").locate(EXAMPLE); System.out.println(" - debug session..."); // EXAMPLE: short syntax: method call at "location" var valueE = (Double) example.call("methodNum", new Object[]{"3", "7", 3.0}); System.out.printf(" - methodNum = '%s'%n", valueE); // EXAMPLE: short syntax: variable access at "location" var valueF = (Integer) example.variable("counter"); System.out.printf(" - counter = '%s'%n", valueF); // EXAMPLE: short syntax: invoke method inside remote context var valueA = example.eval(context -> { var counter = (Integer) context.variable("counter"); return (Integer) context.call("methodInt", new Object[]{6, counter}); }); System.out.printf(" - methodInt = '%s'%n", valueA); // EXAMPLE: manually create breakpoint & process debug events BreakpointRequest breakpoint = debugger.breakpoint(example); int[] result = {0}; int[] repeat = {0}; debugger.loop(context -> { if (!context.matches(example)) { System.out.printf(" * ignore event: %s%n", context.event()); return Optional.empty(); } Integer counter = (Integer) context.variable("counter"); System.out.printf(" * counter = %d%n", counter); result[0] += counter; if (repeat[0]++ > 10) { breakpoint.setEnabled(false); context.stop(); return Optional.of("calculated"); } return Optional.empty(); }); System.out.printf(" - result = %d%n", result[0]); } catch (VMDisconnectedException e) { System.out.println("Virtual Machine is disconnected."); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("Disconnected."); } } }