Duplicate :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
J2SE Version (please include all output from java -version flag): 7u4 Does this problem occur on J2SE 6ux or 7ux? Yes / No (pick one) No, works fine with 6u32 Bug Description: This issue appears to be due in part to a weird change in ordering in Java 7's object tranversal. In Java 6 (note can provide the Java 6 Update 32 version, but it really doesn't change apart from the version number): <java version="1.6.0_25" class="java.beans.XMLDecoder"> <void id="MBeanLoader0" property="owner"/> <object id="Emailer0" class="wt.jmx.core.mbeans.Emailer"> <void id="ArrayList0" property="emailLists"> <void method="add"> <object class="wt.jmx.core.mbeans.EmailList"> <object idref="Emailer0"/> <string>JMX-Administrators</string> <void property="addressList"> <string>###@###.###</string> </void> </object> </void> </void> <void property="emailLists"> <object idref="ArrayList0"/> </void> <void property="ownerMBean"> <object idref="MBeanLoader0"/> </void> </object> ... In Java 7: <java version="1.7.0_04" class="java.beans.XMLDecoder"> <void id="MBeanLoader0" property="owner"/> <object class="wt.jmx.core.mbeans.Emailer" id="Emailer0"> <void id="ArrayList0" property="emailLists"> <void method="add"> <object class="wt.jmx.core.mbeans.EmailList"> <object idref="Emailer0"> <void property="emailLists"> <object idref="ArrayList0"/> </void> <void property="ownerMBean"> <object idref="MBeanLoader0"/> </void> </object> <string>JMX-Administrators</string> <void property="addressList"> <string>###@###.###</string> </void> </object> </void> </void> </object> ... Java 7's output very slightly more verbose but it also seems to be "eating its own tail" more than the Java 6 output, i.e. it's trying to specify the emailLists property to be ArrayList0 in the midst of creating ArrayList0. The <object idref="Emailer0"> and subsequent <string>JMX-Administrators</string> elements are due to setting a persistence delegate of "new DefaultPersistenceDelegate( new String[] { "emailer", "name" } )" for the EmailList class. This change was simply ugly, but the result is that XMLDecoder fails to add the EmailList instance to the Emailer instance, so something seems quite broken here. Steps to Reproduce (be specific): After changing ~70 classes, can once again persist the objects via XMLEncoder. The output is, however, substantially different than that produced with Java 6. That's fine *but* also get numerous exceptions when reading this XML in with XMLDecoder. These are output by the exception listener and are of the form: java.lang.NullPointerException: target should not be null at java.beans.Statement.invokeInternal(Statement.java:201) at java.beans.Statement.access$000(Statement.java:58) at java.beans.Statement$2.run(Statement.java:185) at java.security.AccessController.doPrivileged(Native Method) at java.beans.Statement.invoke(Statement.java:182) at java.beans.Expression.getValue(Expression.java:153) at com.sun.beans.decoder.ObjectElementHandler.getValueObject(ObjectElementHandler.java:166) at com.sun.beans.decoder.NewElementHandler.getValueObject(NewElementHandler.java:123) at com.sun.beans.decoder.ElementHandler.endElement(ElementHandler.java:169) at com.sun.beans.decoder.DocumentHandler.endElement(DocumentHandler.java:305) at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) at org.apache.xerces.jaxp.SAXParserImpl.parse(Unknown Source) at com.sun.beans.decoder.DocumentHandler.parse(DocumentHandler.java:356) at java.beans.XMLDecoder.parsingComplete(XMLDecoder.java:192) at java.beans.XMLDecoder.readObject(XMLDecoder.java:238) ... One piece that may not be 100% obvious from the XML: public synchronized Collection<EmailList> getEmailLists() { return ( new ArrayList<>( emailLists.values() ) ); } public synchronized void setEmailLists( final Collection<EmailList> newEmailLists ) { for ( EmailList emailList : emailLists.values() ) emailList.deregister(); emailLists.clear(); for ( EmailList inEmailList : newEmailLists ) addEmailList( inEmailList ); } the nuances here may explain why the new XML fails -- in that setEmailLists() doesn't literally assign the incoming Collection reference to a field but rather clears its internal collection and then copies each element from the incoming Collection. It would seem that XMLEncoder should work fine with an implementation like this -- and it did all the way through Java 5 and 6. Reading the Java 7 generation XML, however, it would seem that it attempts to assign this Collection to the Emailer object before its first element has been successfully created, which is clearly not right. Seems it is a regression after the 6921644 fix. We should set ArrayList later, when it will be initialized.
|