diff -r 1bcfccf16f90 openide.nodes/src/org/openide/nodes/Sheet.java --- a/openide.nodes/src/org/openide/nodes/Sheet.java Sun Sep 30 19:13:37 2012 -0700 +++ b/openide.nodes/src/org/openide/nodes/Sheet.java Sun Oct 28 12:50:26 2012 +0100 @@ -88,7 +88,7 @@ /** Copy constrcutor. * @param ar array to use */ - private Sheet(ArrayList ar) { + Sheet(ArrayList ar) { sets = ar; } diff -r 1bcfccf16f90 openide.nodes/test/unit/src/org/openide/nodes/SheetTest.java --- a/openide.nodes/test/unit/src/org/openide/nodes/SheetTest.java Sun Sep 30 19:13:37 2012 -0700 +++ b/openide.nodes/test/unit/src/org/openide/nodes/SheetTest.java Sun Oct 28 12:50:26 2012 +0100 @@ -47,7 +47,11 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; import org.netbeans.junit.NbTestCase; +import org.openide.nodes.Node.PropertySet; +import org.openide.util.Exceptions; @@ -174,4 +178,47 @@ } + public void testIncorrectSynchronization() { + final CountDownLatch cont = new CountDownLatch(1); + final CountDownLatch finish = new CountDownLatch(1); + final AtomicBoolean testStarted = new AtomicBoolean(); + final Sheet test = new Sheet(new ArrayList() { + @Override + public T[] toArray(T[] a) { + if (testStarted.get()) { + cont.countDown(); + try { + finish.await(); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } + } + return super.toArray(a); + } + }); + + test.put(new Sheet.Set()); + + final boolean[] wasNull = new boolean[1]; + + new Thread() { + @Override public void run() { + try { + cont.await(); + for (PropertySet set : test.toArray()) { + wasNull[0] |= set == null; + } + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } + finish.countDown(); + } + }.start(); + + testStarted.set(true); + + test.toArray(); + + assertFalse("No JavaNode in sight, and still returns a null property set?", wasNull[0]); + } }