I am looking for an automatic way to detect violations of the Swing's single threaded policy in my code. I'm looking for something along the lines of some AOP code you drop into the VM while the swing app is running and have it log any places where a swing component is modified outside of the EDT.
I'm not an AOP guy but I would imagine creating an AOP proxy around every java.swing.* class which looks like
AOP_before(Method m, Object args[]) {
if (!isEventDispatchThread(Thread.currentThread()) {
logStack(new RuntimeException("violation!"));
}
invoke(m, args);
}
Anyone know of a project or utility that does this?
I haven't used this particular one, but this CheckThreadViolationRepaintManager should do the trick.
It does have the requirement of adding:
RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
to your code however.
I've found a 4 years old blog post describing some solutions, but would be really interested if you find one which detects the most EDT violations. The RepaintManager seems not to be bullet proof in detecting all violations.
For posterity's sake, here's a simplified version of the CheckThreadViolationRepaintManager that TofuBeer found.
RepaintManager.setCurrentManager(new RepaintManager() {
public synchronized void addInvalidComponent( JComponent component ) {
check( component );
super.addInvalidComponent( component );
}
public void addDirtyRegion( JComponent component, int x, int y, int w, int h ) {
check( component );
super.addDirtyRegion( component, x, y, w, h );
}
private void check( JComponent c ) {
if( !SwingUtilities.isEventDispatchThread() && c.isShowing() ) {
new Throwable("EDT required!").printStackTrace();
}
}
});
Just call that in your main method and you'll get stacktraces logged whenever components are being changed on non-EDT threads.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With