I am using the JDI to recode the variable status in the method. According to the tutorial, I am not found how to get objectReference value, like List, Map or my custom class. It just can get PrimtiveValue.
StackFrame stackFrame = ((BreakpointEvent) event).thread().frame(0);
Map<LocalVariable, Value> visibleVariables = (Map<LocalVariable, Value>) stackFrame
.getValues(stackFrame.visibleVariables());
for (Map.Entry<LocalVariable, Value> entry : visibleVariables.entrySet()) {
System.out.println("console->>" + entry.getKey().name() + " = " + entry.getValue());
}
}
if LocalVariable is PrimtiveValue type, like int a = 10;
, then it will print
console->> a = 10
if LocalVariable is ObjectReference type, like Map data = new HashMap();data.pull("a",10)
, then it will print
console->> data = instance of java.util.HashMap(id=101)
But I want to get result like below
console->> data = {a:10} // as long as get the data of reference value
Thanks!
There is no 'value' of an ObjectReference
. It is itself an instance of Value
.
What you probably want is to get a string representation of an object referenced by this ObjectReference
. In this case you need to call toString()
method on that object.
Call ObjectReference.invokeMethod
passing a Method
for toString()
. As a result, you'll get a StringReference
instance, on which you then call value()
to obtain the desired string representation.
for (Map.Entry<LocalVariable, Value> entry : visibleVariables.entrySet()) {
String name = entry.getKey().name();
Value value = entry.getValue();
if (value instanceof ObjectReference) {
ObjectReference ref = (ObjectReference) value;
Method toString = ref.referenceType()
.methodsByName("toString", "()Ljava/lang/String;").get(0);
try {
value = ref.invokeMethod(thread, toString, Collections.emptyList(), 0);
} catch (Exception e) {
// Handle error
}
}
System.out.println(name + " : " + value);
}