This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 256943 - activeReferenceQueue bug: ChildrenLazyKeysTest is failing often
Summary: activeReferenceQueue bug: ChildrenLazyKeysTest is failing often
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Lookup (show other bugs)
Version: 8.2
Hardware: All All
: P2 normal (vote)
Assignee: Martin Entlicher
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-12-03 08:35 UTC by Martin Entlicher
Modified: 2015-12-17 12:18 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
This test demonstrates the issue. (1.92 KB, patch)
2015-12-05 12:33 UTC, Martin Entlicher
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Entlicher 2015-12-03 08:35:38 UTC
Two tests in ChildrenLazyKeysTest are failing often:
  org.openide.nodes.ChildrenLazyKeysTest.testDestroyIsCalledWhenANodeIsRemoved
  org.openide.nodes.ChildrenLazyKeysTest.testGCKeys

They should either be stabilized, or marked as @RandomlyFails again.
Comment 1 Martin Entlicher 2015-12-03 16:52:12 UTC
The core of the problem is, that the ActiveQueue.Impl, which is used in class W through Utilities.activeReferenceQueue(), gets GC'ed.
This can happen even while an instance of W lives, because W.queue (meaning java.lang.ref.Reference.queue) is replaced with ReferenceQueue.ENQUEUED in ReferenceQueue.enqueue(). After ActiveQueue.Impl gets GC'ed, nobody calls W.run() any more.
Comment 2 Martin Entlicher 2015-12-03 17:45:43 UTC
I do not know what the proper Bug's component is, the ActiveQueue implementation is in org.openide.util.lookup.implspi package, but it has nothing to do with lookup.

This is a defect of ActiveQueue.

Explanation:

The test creates an instance of ChildrenKeysTest$1W reference with the ActiveQueue$Impl being it's queue. It refers to an object, which is GC'ed soon.
Therefore, at some point, Reference.ReferenceHandler thread enqueues the ChildrenKeysTest$1W reference into ActiveQueue$Impl, which replaces the ChildrenKeysTest$1W.queue with ENQUEUED and notifies a lock, which is shared between ActiveQueue$Impl and ActiveQueue.ACTIVE queues. Since ActiveQueue$Impl is held weakly, it can get GC'ed then.
Daemon.run() is resumed from wait after the shared lock is notified, but obtainQueue() returns null, since activeReferenceQueue was GC'ed already. Thus it can not call pollSuper() on it and get the ChildrenKeysTest$1W instance and thus nobody calls ChildrenKeysTest$1W.run() even though the reference' object was GC'ed and the test still holds the reference.

The test can be fixed by holding the reference queue obtained from Utilities.activeReferenceQueue(), but that would only mask the error.
Comment 3 Martin Entlicher 2015-12-03 18:24:36 UTC
I'm not sure how this can be fixed while keeping the current implementation ideas.
We might look forward to a good implementation of https://bugs.openjdk.java.net/browse/JDK-8138696, but the current proposal does not meet the goals of our ActiveQueue.
Comment 4 Martin Entlicher 2015-12-05 12:33:34 UTC
Created attachment 157680 [details]
This test demonstrates the issue.

Attaching a test that demonstrates this issue. The test never finishes (timeouts), because the references' queue gets GC'ed and thus nobody calls the Runnables.
Comment 5 Martin Entlicher 2015-12-05 12:37:42 UTC
IMHO the only reliable fix is to hold the ActiveQueue$Impl on a strong reference and never shut down the Daemon thread.
Then I propose to deprecate BaseUtilities.activeReferenceQueue() and I'm about to propose a new API soon...
Comment 6 Martin Entlicher 2015-12-07 10:17:00 UTC
Fixed by changeset:   294408:00704fa1e16b
http://hg.netbeans.org/core-main/rev/00704fa1e16b
See issue #257013 for an alternative API.
Comment 7 Quality Engineering 2015-12-08 05:46:02 UTC
Integrated into 'main-silver', will be available in build *201512080311* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)

Changeset: http://hg.netbeans.org/main-silver/rev/00704fa1e16b
User: mentlicher@netbeans.org
Log: #256943: Hold the activeReferenceQueue on a string reference and run the Daemon thread indefinitely. A new test added for correct functionality.
Comment 8 Martin Entlicher 2015-12-17 12:18:09 UTC
I do not think we want to add this into the patch, in the end.
The problem manifests when the active reference queue is GC'ed, but during implementation of issue #257013 it turned out, that in an IDE this never happens. There are event components holding the active reference queue in a string static reference.
Fixing this helps tests and other non-IDE usage of the NetBeans platform.