BAEL-2846- Intro to the Java Debug Interface (#7606)
This commit is contained in:
parent
5bc7d85eee
commit
b5272dedb5
130
java-jdi/pom.xml
Normal file
130
java-jdi/pom.xml
Normal file
@ -0,0 +1,130 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>java-jdi</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>java-jdi</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>${jmh-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>${jmh-generator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>${tools.version}</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>java-jdi</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>${maven-javadoc-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<commons-lang3.version>3.5</commons-lang3.version>
|
||||
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<tool.version>1.8</tool.version>
|
||||
<org.slf4j.version>1.7.21</org.slf4j.version>
|
||||
<logback.version>1.1.7</logback.version>
|
||||
<tools.version>1.8</tools.version>
|
||||
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
||||
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
|
||||
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
|
||||
</properties>
|
||||
</project>
|
14
java-jdi/src/main/java/com/baeldung/jdi/JDIExample.java
Normal file
14
java-jdi/src/main/java/com/baeldung/jdi/JDIExample.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.baeldung.jdi;
|
||||
|
||||
public class JDIExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String jpda = "Java Platform Debugger Architecture";
|
||||
System.out.println("Hi Everyone, Welcome to " + jpda); //add a break point here
|
||||
|
||||
String jdi = "Java Debug Interface"; //add a break point here and also stepping in here
|
||||
String text = "Today, we'll dive into " + jdi;
|
||||
System.out.println(text);
|
||||
}
|
||||
|
||||
}
|
171
java-jdi/src/main/java/com/baeldung/jdi/JDIExampleDebugger.java
Normal file
171
java-jdi/src/main/java/com/baeldung/jdi/JDIExampleDebugger.java
Normal file
@ -0,0 +1,171 @@
|
||||
package com.baeldung.jdi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.jdi.AbsentInformationException;
|
||||
import com.sun.jdi.Bootstrap;
|
||||
import com.sun.jdi.ClassType;
|
||||
import com.sun.jdi.IncompatibleThreadStateException;
|
||||
import com.sun.jdi.LocalVariable;
|
||||
import com.sun.jdi.Location;
|
||||
import com.sun.jdi.StackFrame;
|
||||
import com.sun.jdi.VMDisconnectedException;
|
||||
import com.sun.jdi.Value;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.connect.Connector;
|
||||
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
|
||||
import com.sun.jdi.connect.LaunchingConnector;
|
||||
import com.sun.jdi.connect.VMStartException;
|
||||
import com.sun.jdi.event.BreakpointEvent;
|
||||
import com.sun.jdi.event.ClassPrepareEvent;
|
||||
import com.sun.jdi.event.Event;
|
||||
import com.sun.jdi.event.EventSet;
|
||||
import com.sun.jdi.event.LocatableEvent;
|
||||
import com.sun.jdi.event.StepEvent;
|
||||
import com.sun.jdi.request.BreakpointRequest;
|
||||
import com.sun.jdi.request.ClassPrepareRequest;
|
||||
import com.sun.jdi.request.StepRequest;
|
||||
|
||||
public class JDIExampleDebugger {
|
||||
|
||||
private Class debugClass;
|
||||
private int[] breakPointLines;
|
||||
|
||||
public Class getDebugClass() {
|
||||
return debugClass;
|
||||
}
|
||||
|
||||
public void setDebugClass(Class debugClass) {
|
||||
this.debugClass = debugClass;
|
||||
}
|
||||
|
||||
public int[] getBreakPointLines() {
|
||||
return breakPointLines;
|
||||
}
|
||||
|
||||
public void setBreakPointLines(int[] breakPointLines) {
|
||||
this.breakPointLines = breakPointLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the debug class as the main argument in the connector and launches the VM
|
||||
* @return VirtualMachine
|
||||
* @throws IOException
|
||||
* @throws IllegalConnectorArgumentsException
|
||||
* @throws VMStartException
|
||||
*/
|
||||
public VirtualMachine connectAndLaunchVM() throws IOException, IllegalConnectorArgumentsException, VMStartException {
|
||||
LaunchingConnector launchingConnector = Bootstrap.virtualMachineManager().defaultConnector();
|
||||
Map<String, Connector.Argument> arguments = launchingConnector.defaultArguments();
|
||||
arguments.get("main").setValue(debugClass.getName());
|
||||
VirtualMachine vm = launchingConnector.launch(arguments);
|
||||
return vm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a request to prepare the debug class, add filter as the debug class and enables it
|
||||
* @param vm
|
||||
*/
|
||||
public void enableClassPrepareRequest(VirtualMachine vm) {
|
||||
ClassPrepareRequest classPrepareRequest = vm.eventRequestManager().createClassPrepareRequest();
|
||||
classPrepareRequest.addClassFilter(debugClass.getName());
|
||||
classPrepareRequest.enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the break points at the line numbers mentioned in breakPointLines array
|
||||
* @param vm
|
||||
* @param event
|
||||
* @throws AbsentInformationException
|
||||
*/
|
||||
public void setBreakPoints(VirtualMachine vm, ClassPrepareEvent event) throws AbsentInformationException {
|
||||
ClassType classType = (ClassType) event.referenceType();
|
||||
for(int lineNumber: breakPointLines) {
|
||||
Location location = classType.locationsOfLine(lineNumber).get(0);
|
||||
BreakpointRequest bpReq = vm.eventRequestManager().createBreakpointRequest(location);
|
||||
bpReq.enable();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the visible variables
|
||||
* @param event
|
||||
* @throws IncompatibleThreadStateException
|
||||
* @throws AbsentInformationException
|
||||
*/
|
||||
public void displayVariables(LocatableEvent event) throws IncompatibleThreadStateException, AbsentInformationException {
|
||||
StackFrame stackFrame = event.thread().frame(0);
|
||||
if(stackFrame.location().toString().contains(debugClass.getName())) {
|
||||
Map<LocalVariable, Value> visibleVariables = stackFrame.getValues(stackFrame.visibleVariables());
|
||||
System.out.println("Variables at " +stackFrame.location().toString() + " > ");
|
||||
for (Map.Entry<LocalVariable, Value> entry : visibleVariables.entrySet()) {
|
||||
System.out.println(entry.getKey().name() + " = " + entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables step request for a break point
|
||||
* @param vm
|
||||
* @param event
|
||||
*/
|
||||
public void enableStepRequest(VirtualMachine vm, BreakpointEvent event) {
|
||||
//enable step request for last break point
|
||||
if(event.location().toString().contains(debugClass.getName()+":"+breakPointLines[breakPointLines.length-1])) {
|
||||
StepRequest stepRequest = vm.eventRequestManager().createStepRequest(event.thread(), StepRequest.STEP_LINE, StepRequest.STEP_OVER);
|
||||
stepRequest.enable();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
JDIExampleDebugger debuggerInstance = new JDIExampleDebugger();
|
||||
debuggerInstance.setDebugClass(JDIExample.class);
|
||||
int[] breakPoints = {6, 9};
|
||||
debuggerInstance.setBreakPointLines(breakPoints);
|
||||
VirtualMachine vm = null;
|
||||
|
||||
try {
|
||||
vm = debuggerInstance.connectAndLaunchVM();
|
||||
debuggerInstance.enableClassPrepareRequest(vm);
|
||||
|
||||
EventSet eventSet = null;
|
||||
while ((eventSet = vm.eventQueue().remove()) != null) {
|
||||
for (Event event : eventSet) {
|
||||
if (event instanceof ClassPrepareEvent) {
|
||||
debuggerInstance.setBreakPoints(vm, (ClassPrepareEvent)event);
|
||||
}
|
||||
|
||||
if (event instanceof BreakpointEvent) {
|
||||
event.request().disable();
|
||||
debuggerInstance.displayVariables((BreakpointEvent) event);
|
||||
debuggerInstance.enableStepRequest(vm, (BreakpointEvent)event);
|
||||
}
|
||||
|
||||
if (event instanceof StepEvent) {
|
||||
debuggerInstance.displayVariables((StepEvent) event);
|
||||
}
|
||||
vm.resume();
|
||||
}
|
||||
}
|
||||
} catch (VMDisconnectedException e) {
|
||||
System.out.println("Virtual Machine is disconnected.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
InputStreamReader reader = new InputStreamReader(vm.process().getInputStream());
|
||||
OutputStreamWriter writer = new OutputStreamWriter(System.out);
|
||||
char[] buf = new char[512];
|
||||
|
||||
reader.read(buf);
|
||||
writer.write(buf);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
2
pom.xml
2
pom.xml
@ -457,6 +457,7 @@
|
||||
<module>java-collections-conversions</module>
|
||||
<module>java-collections-maps</module>
|
||||
<module>java-collections-maps-2</module>
|
||||
<module>java-jdi</module>
|
||||
<!-- <module>java-dates</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 -->
|
||||
<!-- <module>java-dates-2</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 -->
|
||||
<!-- <module>java-ee-8-security-api</module> --> <!-- long running -->
|
||||
@ -1156,6 +1157,7 @@
|
||||
<module>java-collections-conversions</module>
|
||||
<module>java-collections-maps</module>
|
||||
<module>java-collections-maps-2</module>
|
||||
<module>java-jdi</module>
|
||||
<!-- <module>java-dates</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 -->
|
||||
<module>java-ee-8-security-api</module>
|
||||
<module>java-lite</module>
|
||||
|
Loading…
x
Reference in New Issue
Block a user