Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect Swing thread policy violations

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?

like image 590
Justin Avatar asked Jun 30 '10 21:06

Justin


3 Answers

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.

like image 194
TofuBeer Avatar answered Nov 08 '22 17:11

TofuBeer


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.

like image 29
Tobias P. Avatar answered Nov 08 '22 17:11

Tobias P.


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.

like image 3
Epaga Avatar answered Nov 08 '22 17:11

Epaga