JDK-6684401 : JTree isExpanded should not call itself recursively
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-04-04
  • Updated: 2011-02-16
  • Resolved: 2008-07-28
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u11Fixed 7Fixed
Description
FULL PRODUCT VERSION :
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b05)
Java HotSpot(TM) Client VM (build 1.6.0_02-b05, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
JTree isExpanded(TreePath) is unnecessarily recursive. With the default stack size (or any reasonable size) a TreePath to a few thousand entries will lead to StackOverflowException. Trees are used to represent graphs, e.g., reference chains that can easily exceed this depth. isExpanded(TreePath) can be trivially rewritten as a loop.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In a loop, lengthen a path by adding children to a branch of a tree, one per level, and keep calling isVisible() on the TreePath that represents the deepest child until you get StackOverflowException.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Some degradation in speed, but no exceptions.
ACTUAL -
StackOverflowException when isVisible(TreePath) calls isExpanded(TreePath).

REPRODUCIBILITY :
This bug can be reproduced always.

Comments
SUGGESTED FIX public boolean isExpanded(TreePath path) { Object value; if(path == null) return false; do{ value = expandedState.get(path); if(value == null || !((Boolean)value).booleanValue()) return false; }while( (path=path.getParentPath())!=null ); return true; }
27-06-2008

EVALUATION Assigned to JTree owner
10-04-2008