#463 Race condition from updating object tree with user thread

2.3.1
open
Rob Manning
Core (461)
5
2015-02-22
2006-12-09
Rob Manning
No

We have a case in the object tree code where we are mutating the structure of the tree outside of the event thread. Initial analysis indicates that any call to ObjectTreeNode.add that is not running in the event thread should be placed there. There may be other methods in this class that need to have the same treatment applied. So, for instance instead of doing
this:

public void add(MutableTreeNode newChild)
{
super.add(newChild);
newChild.setParent(this);
}

Maybe we should be doing something like:

public void add(MutableTreeNode newChild)
{
GUIUtils.processOnSwingEventThread(new Runnable() {
public void run() {
super.add(newChild);
newChild.setParent(this);
}
});

}

The following stack trace - with ArrayIndexOutOfBoundsExceptions indicating the issue - was obtained from user Melinda Savoy(The NPEs are already fixed in 2.3.2 and the trunk):

8855737 [Thread-2] ERROR
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask - Could not
update cache
java.lang.NullPointerException
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoCache.c
learTables(SchemaInfoCache.java:428)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.reload
(SchemaInfo.java:1247)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.refers
hCacheForSimpleTableName(SchemaInfo.java:1374)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoUpdateC
heck.flush(SchemaInfoUpdateCheck.java:165)
at
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask.run(SQLExecu
terTask.java:303)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
9095269 [Thread-7] ERROR
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask - Could not
update cache
java.lang.NullPointerException
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoCache.c
learTables(SchemaInfoCache.java:428)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.reload
(SchemaInfo.java:1247)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoUpdateC
heck.flush(SchemaInfoUpdateCheck.java:159)
at
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask.run(SQLExecu
terTask.java:303)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
9443756 [Thread-8] ERROR
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask - Could not
update cache
java.lang.NullPointerException
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoCache.c
learTables(SchemaInfoCache.java:428)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.reload
(SchemaInfo.java:1247)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.refers
hCacheForSimpleTableName(SchemaInfo.java:1374)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoUpdateC
heck.flush(SchemaInfoUpdateCheck.java:165)
at
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask.run(SQLExecu
terTask.java:303)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
10632746 [Thread-25] ERROR
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask - Could not
update cache
java.lang.NullPointerException
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoCache.c
learTables(SchemaInfoCache.java:428)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.reload
(SchemaInfo.java:1247)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.refers
hCacheForSimpleTableName(SchemaInfo.java:1374)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoUpdateC
heck.flush(SchemaInfoUpdateCheck.java:165)
at
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask.run(SQLExecu
terTask.java:303)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
10632839 [Thread-31] ERROR
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree - Error: localhost
java.lang.ArrayIndexOutOfBoundsException: 1 > 0
at java.util.Vector.insertElementAt(Vector.java:558)
at
javax.swing.tree.DefaultMutableTreeNode.insert(DefaultMutableTreeNode.ja
va:177)
at
javax.swing.tree.DefaultMutableTreeNode.add(DefaultMutableTreeNode.java:
396)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
reeNode.add(ObjectTreeNode.java:86)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$TreeLoader.loadChildren(ObjectTree.java:1010)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$TreeLoader.execute(ObjectTree.java:929)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.expandNode(ObjectTree.java:538)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.access$1500(ObjectTree.java:72)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$ExpansionController.run(ObjectTree.java:879)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
10820125 [Thread-7] ERROR
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask - Could not
update cache
java.lang.NullPointerException
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoCache.c
learTables(SchemaInfoCache.java:428)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.reload
(SchemaInfo.java:1247)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.refers
hCacheForSimpleTableName(SchemaInfo.java:1374)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoUpdateC
heck.flush(SchemaInfoUpdateCheck.java:165)
at
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask.run(SQLExecu
terTask.java:303)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
10820250 [AWT-EventQueue-1] ERROR
net.sourceforge.squirrel_sql.client.Application - Exception occured
dispatching Event
java.awt.event.InvocationEvent[INVOCATION_DEFAULT,runnable=net.sourcefor
ge.squirrel_sql.client.session.schemainfo.SchemaInfo$7@1329346,notifier=
null,catchExceptions=false,when=1165505742196] on
sun.awt.windows.WToolkit@167d940
java.lang.ArrayIndexOutOfBoundsException: 11 >= 11
at java.util.Vector.removeElementAt(Vector.java:518)
at
javax.swing.tree.DefaultMutableTreeNode.remove(DefaultMutableTreeNode.ja
va:192)
at
javax.swing.tree.DefaultMutableTreeNode.removeAllChildren(DefaultMutable
TreeNode.java:377)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.refreshTree(ObjectTree.java:331)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.access$900(ObjectTree.java:72)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$3$1.run(ObjectTree.java:302)
at
net.sourceforge.squirrel_sql.fw.gui.GUIUtils.processOnSwingEventThread(G
UIUtils.java:386)
at
net.sourceforge.squirrel_sql.fw.gui.GUIUtils.processOnSwingEventThread(G
UIUtils.java:351)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$3.run(ObjectTree.java:298)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.refresh(ObjectTree.java:315)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
reePanel.refreshTree(ObjectTreePanel.java:631)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
reePanel$2.schemaInfoUpdated(ObjectTreePanel.java:229)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo$7.run(
SchemaInfo.java:1341)
at
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at
net.sourceforge.squirrel_sql.client.Application$1.dispatchEvent(Applicat
ion.java:168)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThrea
d.java:242)
at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.
java:163)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at
java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
11004238 [Thread-4] ERROR
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask - Could not
update cache
java.lang.NullPointerException
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoCache.c
learTables(SchemaInfoCache.java:428)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.reload
(SchemaInfo.java:1247)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.refers
hCacheForSimpleTableName(SchemaInfo.java:1374)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoUpdateC
heck.flush(SchemaInfoUpdateCheck.java:165)
at
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask.run(SQLExecu
terTask.java:303)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
11004363 [AWT-EventQueue-1] ERROR
net.sourceforge.squirrel_sql.client.Application - Exception occured
dispatching Event
java.awt.event.InvocationEvent[INVOCATION_DEFAULT,runnable=net.sourcefor
ge.squirrel_sql.client.session.mainpanel.objecttree.ObjectTree$TreeLoade
r$1@866f20,notifier=null,catchExceptions=false,when=1165505927466] on
sun.awt.windows.WToolkit@167d940
java.lang.ArrayIndexOutOfBoundsException: 13 >= 13
at java.util.Vector.elementAt(Vector.java:432)
at
javax.swing.tree.DefaultMutableTreeNode.getChildAt(DefaultMutableTreeNod
e.java:230)
at
javax.swing.tree.DefaultTreeModel.getChild(DefaultTreeModel.java:156)
at
javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.expand(Variable
HeightLayoutCache.java:1475)
at
javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.expand(Variable
HeightLayoutCache.java:1270)
at
javax.swing.tree.VariableHeightLayoutCache.rebuild(VariableHeightLayoutC
ache.java:725)
at
javax.swing.tree.VariableHeightLayoutCache.treeStructureChanged(Variable
HeightLayoutCache.java:626)
at
javax.swing.plaf.basic.BasicTreeUI$Handler.treeStructureChanged(BasicTre
eUI.java:3721)
at
javax.swing.tree.DefaultTreeModel.fireTreeStructureChanged(DefaultTreeMo
del.java:559)
at
javax.swing.tree.DefaultTreeModel.nodeStructureChanged(DefaultTreeModel.
java:345)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$TreeLoader$1.run(ObjectTree.java:1025)
at
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at
net.sourceforge.squirrel_sql.client.Application$1.dispatchEvent(Applicat
ion.java:168)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThrea
d.java:242)
at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.
java:163)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at
java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
11400261 [Thread-29] ERROR
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask - Could not
update cache
java.lang.NullPointerException
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoCache.c
learTables(SchemaInfoCache.java:428)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.reload
(SchemaInfo.java:1247)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo.refers
hCacheForSimpleTableName(SchemaInfo.java:1374)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfoUpdateC
heck.flush(SchemaInfoUpdateCheck.java:165)
at
net.sourceforge.squirrel_sql.client.session.SQLExecuterTask.run(SQLExecu
terTask.java:303)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
11401198 [Thread-32] ERROR
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree - Error: localhost
java.lang.ArrayIndexOutOfBoundsException: 1 > 0
at java.util.Vector.insertElementAt(Vector.java:558)
at
javax.swing.tree.DefaultMutableTreeNode.insert(DefaultMutableTreeNode.ja
va:177)
at
javax.swing.tree.DefaultMutableTreeNode.add(DefaultMutableTreeNode.java:
396)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
reeNode.add(ObjectTreeNode.java:86)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$TreeLoader.loadChildren(ObjectTree.java:1010)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$TreeLoader.execute(ObjectTree.java:929)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.expandNode(ObjectTree.java:538)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.access$1500(ObjectTree.java:72)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$ExpansionController.run(ObjectTree.java:879)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
11491700 [Thread-24] ERROR
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree - Error: localhost
java.lang.ArrayIndexOutOfBoundsException: 9 > 5
at java.util.Vector.insertElementAt(Vector.java:558)
at
javax.swing.tree.DefaultMutableTreeNode.insert(DefaultMutableTreeNode.ja
va:177)
at
javax.swing.tree.DefaultMutableTreeNode.add(DefaultMutableTreeNode.java:
396)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
reeNode.add(ObjectTreeNode.java:86)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$TreeLoader.loadChildren(ObjectTree.java:1010)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$TreeLoader.execute(ObjectTree.java:929)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.expandNode(ObjectTree.java:538)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.access$1500(ObjectTree.java:72)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$ExpansionController.run(ObjectTree.java:879)
at
net.sourceforge.squirrel_sql.fw.util.TaskExecuter.run(TaskExecuter.java:
82)
at java.lang.Thread.run(Thread.java:595)
11491700 [AWT-EventQueue-1] ERROR
net.sourceforge.squirrel_sql.client.Application - Exception occured
dispatching Event
java.awt.event.InvocationEvent[INVOCATION_DEFAULT,runnable=net.sourcefor
ge.squirrel_sql.client.session.schemainfo.SchemaInfo$7@18da1c6,notifier=
null,catchExceptions=false,when=1165506414412] on
sun.awt.windows.WToolkit@167d940
java.lang.ArrayIndexOutOfBoundsException: 1 >= 1
at java.util.Vector.elementAt(Vector.java:432)
at
javax.swing.tree.DefaultMutableTreeNode.getChildAt(DefaultMutableTreeNod
e.java:230)
at
javax.swing.tree.DefaultMutableTreeNode.remove(DefaultMutableTreeNode.ja
va:191)
at
javax.swing.tree.DefaultMutableTreeNode.removeAllChildren(DefaultMutable
TreeNode.java:377)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.refreshTree(ObjectTree.java:331)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.access$900(ObjectTree.java:72)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$3$1.run(ObjectTree.java:302)
at
net.sourceforge.squirrel_sql.fw.gui.GUIUtils.processOnSwingEventThread(G
UIUtils.java:386)
at
net.sourceforge.squirrel_sql.fw.gui.GUIUtils.processOnSwingEventThread(G
UIUtils.java:351)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree$3.run(ObjectTree.java:298)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
ree.refresh(ObjectTree.java:315)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
reePanel.refreshTree(ObjectTreePanel.java:631)
at
net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectT
reePanel$2.schemaInfoUpdated(ObjectTreePanel.java:229)
at
net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo$7.run(
SchemaInfo.java:1341)
at
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at
net.sourceforge.squirrel_sql.client.Application$1.dispatchEvent(Applicat
ion.java:168)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThrea
d.java:242)
at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.
java:163)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at
java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

Rob

Discussion