Reputation: 3676
I want to know if there's any way so I could watch for variable value change when the program is running. Of course not using debugger I wanna do it Programmatically. For example:
class A
{
public static int valueToBeWatched;
}
So at runtime if in any method of any class in my project modifies this value MyValueChangeListner
event should get called.
Upvotes: 8
Views: 24481
Reputation: 145
If you can use the latest Java SE JDK from Oracle, then I suggest using the javafx.beans.property and javafx.beans.value APIs.
Here is some basic code:
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
public class ObservableValues
{
public static void main(String[] args)
{
DoubleProperty dp = new SimpleDoubleProperty(9);
dp.addListener( new DoubleChangeListener() );
dp.setValue(3);
dp.setValue(6);
}
static class DoubleChangeListener implements ChangeListener<Number>
{
@Override
public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue)
{
System.out.println("the value has changed from " + oldValue + " to " + newValue);
}
}
}
Here is the output:
the value has changed from 9.0 to 3.0
the value has changed from 3.0 to 6.0
Upvotes: 5
Reputation: 17945
The question, as stated, can be solved by writing an Agent to listen to changes on the provided field (see fieldWatch). The Agent would have to be compiled using a C-calling-compatible language, and invoked on VM start with an -agentpath:<path-to-agent>=<options>
switch.
A higher-level option is to attach to a running process using JPDA/JDI, which wraps the above call in a (Java) ModificationWatchpointEvent.
Upvotes: 1
Reputation: 533492
You need to replace the type int
with a class which will invoke your listener whenever the values changes. You might like to ignore setting the value when it hasn't actually changed.
e.g.
private int value;
private final MyValueChangeListener listener;
public void setValue(int value) {
if(this.value == value) return;
listener.changed(this, this.value, value);
this.value = value;
}
You can perform this replace using byte code injection, but it is much simple to change the original code.
An alternative is to monitor the value to look for changes periodically. Unless the value changes very slowly you might not see every change. You can use the Debugger API to do this but it not simple and I wouldn't suggest you use it unless you are familiar with the API already.
Java Debugger API Links
http://java.sun.com/javase/technologies/core/toolsapis/jpda/
http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/
http://docs.oracle.com/javase/6/docs/jdk/api/jpda/jdi/
Upvotes: 9
Reputation: 77454
You cannot. There is no watch-on-modification hook built into Java itself. Obviously, you could do polling, though. But then it won't be "live".
AspectJ may allow such a think, but I'm not sure whether it holds for primitive variables, or only when you are using getters and setters.
The clean Java-way is to make the variable private
and use getters and setters.
private valueToBeWatched;
public void setValue(int newval) {
valueToBeWatched = newval;
notifyWatchers();
}
public int getValue() {
return valueToBeWatched;
}
On a side note, avoid static
whenever possible. In particular public
but not final
.
Upvotes: 13