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 167395 - Singleton TopComponents initalised twice with 6.7 TopComponent wizard
Summary: Singleton TopComponents initalised twice with 6.7 TopComponent wizard
Status: VERIFIED FIXED
Alias: None
Product: apisupport
Classification: Unclassified
Component: Templates (show other bugs)
Version: 6.x
Hardware: All All
: P2 blocker with 2 votes (vote)
Assignee: Jaroslav Tulach
URL: http://forums.netbeans.org/post-38871...
Keywords:
Depends on:
Blocks:
 
Reported: 2009-06-19 21:32 UTC by dandubois
Modified: 2009-10-28 19:16 UTC (History)
3 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description dandubois 2009-06-19 21:32:28 UTC
The Window Component wizard's inclusion of the @ConvertAsProperties annotation on singleton TopComponents seems to make
my singleton TopComponents constructors get called twice when running my application more than once.
Comment 1 arittner 2009-07-23 14:02:16 UTC
I've the same problem. NetBeans creates my TopComponent with two instances.

With a new Exception().printStackTrace(); I get this output:

Code:

java.lang.Exception
        at org.sepix.tutorialbuilder.ui.GalleryTopComponent.<init>(GalleryTopComponent.java:48)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at java.lang.Class.newInstance0(Class.java:355)
        at java.lang.Class.newInstance(Class.java:308)
        at
org.netbeans.modules.settings.convertors.XMLPropertiesConvertor.defaultInstanceCreate(XMLPropertiesConvertor.java:224)
        at org.netbeans.modules.settings.convertors.XMLPropertiesConvertor.read(XMLPropertiesConvertor.java:95)
        at org.netbeans.modules.settings.InstanceProvider$InstanceCookieImpl.instanceCreate(InstanceProvider.java:307)
        at
org.netbeans.core.windows.persistence.PersistenceManager.getTopComponentPersistentForID(PersistenceManager.java:530)
        at org.netbeans.core.windows.persistence.PersistenceManager.getTopComponentForID(PersistenceManager.java:640)
        at org.netbeans.core.windows.PersistenceHandler.getTopComponentForID(PersistenceHandler.java:457)
        at org.netbeans.core.windows.PersistenceHandler.load(PersistenceHandler.java:145)
        at org.netbeans.core.windows.WindowSystemImpl.load(WindowSystemImpl.java:77)
        at org.netbeans.core.NonGui$2.run(NonGui.java:184)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:104)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
java.lang.Exception
        at org.sepix.tutorialbuilder.ui.GalleryTopComponent.<init>(GalleryTopComponent.java:48)
        at org.sepix.tutorialbuilder.ui.GalleryTopComponent.getDefault(GalleryTopComponent.java:102)
        at org.sepix.tutorialbuilder.ui.GalleryTopComponent.readProperties(GalleryTopComponent.java:151)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.netbeans.modules.settings.convertors.XMLPropertiesConvertor.readSetting(XMLPropertiesConvertor.java:253)
        at org.netbeans.modules.settings.convertors.XMLPropertiesConvertor.read(XMLPropertiesConvertor.java:96)
        at org.netbeans.modules.settings.InstanceProvider$InstanceCookieImpl.instanceCreate(InstanceProvider.java:307)
        at
org.netbeans.core.windows.persistence.PersistenceManager.getTopComponentPersistentForID(PersistenceManager.java:530)
        at org.netbeans.core.windows.persistence.PersistenceManager.getTopComponentForID(PersistenceManager.java:640)
        at org.netbeans.core.windows.PersistenceHandler.getTopComponentForID(PersistenceHandler.java:457)
        at org.netbeans.core.windows.PersistenceHandler.load(PersistenceHandler.java:145)
        at org.netbeans.core.windows.WindowSystemImpl.load(WindowSystemImpl.java:77)
        at org.netbeans.core.NonGui$2.run(NonGui.java:184)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:104)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)


Product Version: NetBeans IDE 6.7 (Build 200906241340)
Java: 1.6.0_14-ea; Java HotSpot(TM) Client VM 14.0-b11
System: Windows XP version 5.1 running on x86; Cp1252; de_DE (nb)
Userdir: C:\Dokumente und Einstellungen\Rittner\.netbeans\6.7
Comment 2 polytekpatrick 2009-07-23 18:44:58 UTC
Same problem here. Happens with both NetBeans 6.7 and with the latest development version, when you use the IDE's wizard
to generate a new "Window Component".

I can confirm that the first run after a clean build only executes the TopComponent's constructor once, but following
reruns cause it to execute twice (due to some deserialization scheme). Therefore, the expected singleton pattern is
being broken and the generated code is misleadingly claiming to create a singleton instance when it does not.

Furthermore, the wizard always makes the constructor public, thereby allowing additional unwanted instances to be
created instead of strictly enforcing the singleton pattern with a private constructor. Changing it to private results
in an exception like the following:
java.lang.IllegalAccessException: Class org.netbeans.modules.settings.convertors.XMLPropertiesConvertor can not access a
member of class com.company.example.BadTopComponent with modifiers "private"

Can the wizard's new template in 6.7 be fixed to use a private constructor, to create an actual singleton, and still
make use of the new @ConvertAsProperties annotation thing? If not, I for one will be going back to the 6.5.1 way of
doing things.
Comment 3 Milos Kleint 2009-08-17 14:55:15 UTC
jardo, please comment, introduced by your commits http://hg.netbeans.org/main/rev/dc55cd6092f7 and following..
Comment 4 Jaroslav Tulach 2009-08-18 16:26:38 UTC
Looking at the code I can say that the component is instantiated multiple times, but all other instances are thrown 
away and just one is kept and the one is used for all readPropertiesImpl calls. So the issue shall not be that bad.

fixes#1e286e551363 shall make the default behaviour better.
Comment 5 hidedrive 2009-08-18 16:34:09 UTC
Jtulach, in my case at least the extra instances continue to consume resources in the background. I have one
computationally taxing TopComponent that ran very poorly with the separate instance running, but after commenting the
@ConvertAsProperties line ran quite well. It didn't seem to go away. Have you fixed it so it doesn't create multiple
instances?
Comment 6 arittner 2009-08-18 16:41:19 UTC
"So the issue shall not be that bad."

No, it's really bad :-/. A singleton is a singleton. Not a multiple created Object with a last-one-winner. I've some
plugins with ServiceProvider-Lookups in TopComponent constructors to load Toolbars and "CAD"-Toolbar-Buttons. A double
created object results in performance issues and hard to implement connections between the TopComponent an the found
services. 

Is the issue fixed or not? 

with kind regards, josh.
Comment 7 Quality Engineering 2009-08-21 06:04:34 UTC
Integrated into 'main-golden', will be available in build *200908210201* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/1e286e551363
User: Jaroslav Tulach <jtulach@netbeans.org>
Log: #167395: Bigger attempt to instantiate the component just once
Comment 8 arittner 2009-08-21 09:42:03 UTC
Hi Jaroslav!

Only a template problem? Fantastic, so it's possible to repair the readProperties method in current platform generated
TopComponents. 

The change to 

  Object readProperties(java.util.Properties p) {
    if ( instance == null ) {
      instance = this;
    }
    instance.readPropertiesImpl(p);
    return instance;
  }

works for me. The test Exception appears only one time.

Thank you for the investigation and solution.

br, josh.
Comment 9 Jaroslav Tulach 2009-08-21 10:28:58 UTC
Good to hear that.
Comment 10 rdrr 2009-10-27 15:54:45 UTC
 The main problem here is that the constructor is public allowing it to be created at will from many locations or
through reflection and therefore does not really allow for true singleton behavior. While the submitted fix will work
for the limited problem of the persistence classes calling it twice it does not address the real underlying issue.  In
addition you probably want to modify the current fix to at least be thread safe wrap the instance check in a
synchronized block around the class itself , to block other threads calling the getDefault and findInstance methods that
could happen concurrently to the readProperties call on a specific object.
Comment 11 Jaroslav Tulach 2009-10-28 19:16:53 UTC
Manipulation with Swing components can only happen on EDT, so I probably leave the fix as it is. But if you have a 
patch that others like, I have nothing against applying it.