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.
------------- -- General problem description: ------------- Under Netbeans 4.0 and higher, we cannot use org.openide.explorer.propertysheet.editors.XMLPropertyEditor when building property editors for our visual components. We use this interface on our property editors for Netbeans, and include a copy of the above class file in our jar because we also support all other IDEs (Eclipse, JBuilder) and need this interface present for obvious reasons there. The error is visible when you open a form generated with our wizard that uses the OSetName (XTT defined) property. Our XMLPropertyEditor does not read this property. Attached are a few screen shots showing the warning and error in the IDE, and a text file showing the exception thrown. ----------------- -- Temporary patch is attached ----------------- Also attached are our patches for both 4.0 and 4.1Beta. They would go under ideX\modules\patches\org-netbeans-modules-form where ideX is ide4 or ide5 depending on the NB version. The current changes are all in class GandalfPersistenceManager although my strong suggestion is that it is the classloader used for the ui that should be ultimately fixed. --------------------- --- Details of the problem: --------------------- The real problem is at line 1747 of org.netbeans.modules.form.GandalfPersistenceManager : if (prEd instanceof XMLPropertyEditor) { In that prEd and XMLPropertyEditor are loaded by different classloaders that are not in the same classloader “chain” and therefore instanceof will always return false. Please open attached Debugger.jpg picture at this point. As you can see from the last 2 watches, the XMLPropertyEditor is loaded by org.netbeans.Main$BootClassLoader and our OSetsPropertyEditor is loaded by org.netbeans.api.java.classpath.ClassLoaderSupport. That would not be bad if ClassLoaderSupport would deffer to org.netbeans.Main$BootClassLoader before trying to perform a class load – but it does not. My initial feeling is that as ClassLoaderSupport relies on NbClassLoader to defer the findClass to the system class loader, and NbClassLoader obtains the wrong parent classloader from its constructor: super(new URL[0], systemClassLoader()); In the debugger the call to systemClassLoader() returns a classloader that has nothing to do with org.netbeans.Main$BootClassLoader . Our fix has been to supplement the if (prEd instanceof XMLPropertyEditor) part with extra code that uses the correct classloader to the same effect. Here is an excerpt from the fixed code: if (prEd instanceof XMLPropertyEditor) { // the value is saved by XMLPropertyEditor for (int j=0; j < n; j++) { if (children.item(j).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { // here is the element of stored value ((XMLPropertyEditor)prEd).readFromXML( children.item(j)); value = prEd.getValue(); break; } } } // InsiTech patch for non-Netbeans property editors that use the XMLPropertyEditor interface if ( value == NO_VALUE){ value = patchReadFromXML(prEd , children, n , value); } // if ( value == NO_VALUE) The patchReadFromXML method looks like this: private Object patchReadFromXML(PropertyEditor prEd, org.w3c.dom.NodeList children, int n, Object value ) throws Exception { ClassLoader editorClassLoader = prEd.getClass().getClassLoader(); Class xmlPropertyEditorClass = editorClassLoader.loadClass("org.openide.explorer.propertysheet.editors.XMLPropertyEditor"); if ( xmlPropertyEditorClass != null){ if ( xmlPropertyEditorClass.isAssignableFrom(prEd.getClass())){ // the value is saved by XMLPropertyEditor Method m = prEd.getClass().getMethod("readFromXML" , new Class[]{org.w3c.dom.Node.class}); if ( m != null){ for (int j=0; j < n; j++) { if (children.item(j).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { // here is the element of stored value m.invoke(prEd, new Object[]{ children.item(j)}); return prEd.getValue(); } } } } } return value; // return original value } Please see the full source code for this in the attached patches (form_patch_40.jar and form_patch_41Beta.jar). Again this is just a temporary patch - I feel strongly the the classloader chain should be properly fixed. Thanks, David
Created attachment 21760 [details] Initial Warning
Created attachment 21761 [details] Error Message after initial warning
Created attachment 21762 [details] Full stack trace of exception from the log
Created attachment 21763 [details] Debugger.jpg picture showing classloader instances
Created attachment 21764 [details] Patch for NB 4.0 (contains source also)
Created attachment 21765 [details] Patch for NB 4.1Beta (contains source)
Created attachment 21767 [details] Test source code
Created attachment 21768 [details] Test Code - attach in classpath of project
Created attachment 21769 [details] Test code - attach in classpath of the project
Created attachment 21770 [details] Test code - previous patch for NB 4.0 ONLY - place in {NB4.0}\ide4\modules\patches\org-netbeans-modules-form
XMLPropertyEditor is not intended to be used externally by user classes. We will not integrate this patch for NB 4.1. For a next version of NetBeans we'll try to implement support for the xml beans persistence (via java.beans.XMLEncoder) - to allow for better external control over the property value and bean persistence.