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.
Given NB 3.6 install using SJSAS 8 1. Start NB and create a webapp. 2. Open a text editor on web.xml 3. Open the Configuration Editor on sun-web.xml 4. Drag the configuration editor over to one sice so that both it and web.xml text are simultaneously visible (this makes the bug easier to see). 5. Add text to web.xml that would cause the creation of a child DConfigBean to the Configuration Editor, for example: <servlet> <servlet-name>Foo</servlet-name> </servlet> 6. You should see a Servlet appear in the Configuration editor after typing/pasting the above into web.xml. 7. Select the Servlet Page in the Configuration Editor so that it is visible. 8. Back in web.xml, select the entire servlet block and delete it. 9. You should see the Servlet DConfigBean disappear from the tree in the Configuration Editor. 10. BUG: You will still see the Servlet Customizer (because it was previously selected). You can even still edit with it, for example, adding new items to the WebServiceEndpoint table. When the DConfigBean was removed, the customizer should have had it's bean set to null (otherwise it will hang onto the reference) and a new valid selection in the Configuration Editor (e.g. root node) should be selected to force the display of a new customizer.
While working in this bug on request from Peter W., I discover another behavior: adding servlets to web project does not update the configuration editor. All these 2 behaviors are regression from NB 3.6. I track the regression is from the change to DDProvider to make values of the ddMap to be weak references. This causes WebAppProxy values to be garbage-collected. In turns this cause creation of a new WebAppProxy and associated WebApp on next request from ProjectWebModule. Changes made to WebProject now go to the new WebApp graph without attched PropertyChangeListener from j2eeserver. This cause configuration editor not updated with changes to web.xml. The changes made to DDProvider to use weak references was meant to prevent memory leak on close and reopen a webapp multiple times. Unfortunately, when configuration editor is initialized with a DD's grahp, the graph instance need to be maintained in memory as long as the configuration editor or its associate DO is around. To fix this bug, IMO, we need to maintain DDProvider cache more actively instead of relying on weak references. The attached patch undo the weak reference change and will uncache the WebApp graph on closing project. Milan: I need your opinion on this change to DDProvider. Thanks. In addition, the patch also contain changes to j2eeserver code to reset references to the configuration storage and editor on closing of web project to avoid any possible memory leaks.
Created attachment 16824 [details] web/ddapi and project patch
Created attachment 16825 [details] j2eeserver patch to prevent descriptor cache memory leak on closing project.
This may be a topic for another IZ report, but on the subject of cleanup and references, I would like to null out the DDBean reference held by a DConfigBean when it is removed (via "removeDConfigBean"). However, j2eeserver module is written in such a way as to call 'dcbinstance.getDDBean()' *AFTER* such a remove operation has been performed, so for the sake of stability, such code to null the reference is currently disabled. If j2eeserver is reconfigured so as to not rely on DConfigBeans after it has requested their destruction, we could clean this up and eliminate another reference, in particular, a circular reference, as DDBean's and DConfigBeans by their nature refer to each other.
So, any ideas what the proper and clean fix should be? There have been some brainstormings, but no final resolution. I am writing down some ideas - the final solution may be a combination of several of these ideas: 1) Do not use weak references or WeakHashMap at all - just keep hard references to everything. The obvious disadvantage of this approach is that it creates memory leaks. 2) Use a combination of weak references and hard references. Keep track of listeners listening on the DD API implementation. If there are any listeners, then hard reference will be held, but after the last listener unregisters itself, the hard reference will be cleared, so the WeakReference may release the object in necessary. 3) Get rid of the JSR 88 DDBean implementation in j2eeserver module in package org.netbeans.modules.j2ee.deployment.config. Instead, the DD API directly should implement the JSR 88 DD model. This would allow to hide the BaseBean-based implementation, which is now exposed. The disadvantage is that it makes the DD API implementation more complicated, and creates the need to implement unrelated classes such as javax.enterprise.deploy.model.DeployableObject. 4) Change the JSR 88 DDBean implementation in j2eeserver module to not rely on BaseBeans, but instead use the abstraction from org.netbeans.api.web.dd.common. This abstraction will be common in the whole J2EE, because this code was copied to the EJB DD API module too. 5) Do caching of implementation not at the WebAppProxy level, but at the level of objects that WebAppProxy delegates to. WebAppProxy would be always kept in memory using hard references, creating a small memory leak, which is probably ok. This may allow to better implement idea 2.
The next solution is not to depend on DD API in web project and look for the s2b bean graph directly : the ProjectWebModule:getDeploymentDescriptor() method will create the BaseBean just from the file object without using DDProvider. Then of course the BaseBean object can be cached by the web project.
IMO, the basic underlying issue, regardless of the needed rearchitecture is that, if DDProvider is singlelon, as long as someone using a graph from DDProvider, every requests for this graph should return the same instance so that everybody are "on the same page". This would not be achievable if the weak-referenced cache object just "has" instead of "is" the graph.
FYI: looking at the IDE in JFluid I realized that the memory leak connected to config support and DD is there NOW. So we might as well switch to hard references w/o adding clear method as it does not work anyway (ok, just joking). I am still hoping to: 1. fix the memory leak 2. fix the GC of listeners (both of them at the same time)
The issue described here was fixed by Milan by changing the references from DDProvider from weak to hard. I have now committed a change that fixes the use of weak references so the code seems to work and not use hard references (log bellow). If there are more memory related problems they should be filed separately as the subject of this issues is fixed. cvs commit -m "#42528 improve caching - use weak references correctly" src\org\netbeans\api\web\dd\DDProvider.java (in directory E:\nb_all\web\ddapi\) Checking in src/org/netbeans/api/web/dd/DDProvider.java; /cvs/web/ddapi/src/org/netbeans/api/web/dd/DDProvider.java,v <-- DDProvider.java new revision: 1.14; previous revision: 1.13 done cvs commit -m "#42528 when the DDProvider does not hold the beans in memory weak reference woul..." src\org\netbeans\modules\j2ee\deployment\config\ModuleDeploymentSupport.java (in directory E:\nb_all\j2eeserver\) Checking in src/org/netbeans/modules/j2ee/deployment/config/ModuleDeploymentSupport.java; /cvs/j2eeserver/src/org/netbeans/modules/j2ee/deployment/config/ModuleDeploymentSupport.java,v <-- ModuleDeploymentSupport.java new revision: 1.12; previous revision: 1.11 done