validateTree in Java 7.x doesnt work (in Java 6.x was fine)
Asked Answered
P

2

7

My version of java is:

Java Plug-in 10.3.1.255 Using JRE version 1.7.0_03-b05 Java HotSpot(TM) Client VM

So when I had version 6.x everything was fine, after upgrading I've got this:

    Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: This function should be called while holding treeLock
        at java.awt.Component.checkTreeLock(Component.java:1196)
        at java.awt.Container.validateTree(Container.java:1682)
        at pl.recorder.ScenarioWindow.showUploadPanel(PlayerWindow.java:721)
        at pl.recorder.actions.UploadFilesAction.execute(DesignFilesAction.java:71)
        at pl.recorder.actions.EndTestAction.actionPerformed(EndTestAction.java:91)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
        at java.awt.Component.processMouseEvent(Component.java:6505)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
        at java.awt.Component.processEvent(Component.java:6270)
        at java.awt.Container.processEvent(Container.java:2229)
        at java.awt.Component.dispatchEventImpl(Component.java:4861)
        at java.awt.Container.dispatchEventImpl(Container.java:2287)
        at java.awt.Component.dispatchEvent(Component.java:4687)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
        at java.awt.Container.dispatchEventImpl(Container.java:2273)
        at java.awt.Window.dispatchEventImpl(Window.java:2713)
        at java.awt.Component.dispatchEvent(Component.java:4687)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
        at java.awt.EventQueue.access$000(EventQueue.java:101)
        at java.awt.EventQueue$3.run(EventQueue.java:666)
        at java.awt.EventQueue$3.run(EventQueue.java:664)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
        at java.awt.EventQueue$4.run(EventQueue.java:680)
        at java.awt.EventQueue$4.run(EventQueue.java:678)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

I changed validateTree() to validate() and suprise ;) - everthing works fine, but I dont know if this change will work also on java 6.x (I guess not). How I can change this code to work in Java 6x and 7x.

Passade answered 18/3, 2012 at 11:53 Comment(1)
What code? See also Initial Threads.Tackling
S
11

"It's not a bug, it's a feature" of java 7 ;)

This function should be called while holding treeLock

This is to force you writing :

synchronized(getTreeLock()) {
     validateTree();
}
Square answered 9/7, 2012 at 9:22 Comment(1)
Just received one of this issues when one of my older programs stopped working when I assume client updated their Java to 1.7. This solved the issue :) In my case I wanted to make sure the operations are done when the size of containing components is known and validate was not enough.Green
B
9

In response to @vince's Answer, I think it is instructive to look at what the Java 1.4.2 javadoc for the method says:

protected void validateTree()

Recursively descends the container tree and recomputes the layout for any subtrees marked as needing it (those marked as invalid). Synchronization should be provided by the method that calls this one: validate.

(Emphasis added.)

The way I read this, it is saying that the method is designed to be called by validate() which will (presumably) be holding the tree lock.

Note that the text is identical in Java 6 and Java 7. The spec has not changed ...

Now apparently there is application code out there that is calling validateTree() directly ... without acquiring the tree lock. Presumably, this results in unreproducible problems (Heisenbugs) when the end user clicks too fast or something. Presumably, the change in Java 7 is designed to bring this incorrect / buggy use of validateTree() to developers' attention.

OK, so this is short-term pain. But the long term, everyone wins (apart from the lawyers :-) ):

  • Oracle doesn't get bug reports for strange unreproducible behaviour that is really the application programmer's problem.

  • Developers don't get bug reports from customers for strange unreproducible behaviour.

  • End users get applications that work better.

Burdensome answered 11/10, 2012 at 23:9 Comment(1)
I know this is old, but this helped me and I like to add my two cents. validateTree is protected, so you should call validate instead (it does the synchonized steps). Also, in Java 7 they added a call to checkTreeLock() on validateTree, that's why the error happensAnjaanjali

© 2022 - 2024 — McMap. All rights reserved.