Java Bean Persistence with XMLEncoder -
i've written bean class containing hashmultimap (from guava library). xml encode bean using jre's xmlencoder. using custom persistencedelegate i've written bean file. however, when attempt deserialize xml exception:
java.lang.nosuchmethodexception: <unbound>=hashmultimap.put("pz1", "pz2")
what doing wrong?
// create bean somebean sb = new somebean(); // add data hashmultimap<string, string> statemap = hashmultimap.create(); statemap.put("pz1", "pz2"); statemap.put("pz3", "pz4"); sb.setstatemap(statemap); // encode xml fileoutputstream os = new fileoutputstream("myxmlfile.xml"); xmlencoder encoder = new xmlencoder(os); encoder.setpersistencedelegate(hashmultimap.class, new custompersistencedelegate()); encoder.writeobject(sb); // decode xml fileinputstream = new fileinputstream("myxmlfile.xml"); xmldecoder decoder = new xmldecoder(is); object deserializedobject = decoder.readobject(); class custompersistencedelegate extends defaultpersistencedelegate { protected expression instantiate(object oldinstance, encoder out) { return new expression(oldinstance, oldinstance.getclass(), "create", null); } protected void initialize(class<?> type, object oldinstance, object newinstance, encoder out) { super.initialize(type, oldinstance, newinstance, out); com.google.common.collect.hashmultimap<string, string> m = (com.google.common.collect.hashmultimap) oldinstance; (map.entry<string, string> entry : m.entries()) { out.writestatement(new statement(oldinstance, "put", new object[] { entry.getkey(), entry.getvalue() })); } } } public class somebean { private hashmultimap<string, string> statemap; public hashmultimap<string, string> getstatemap() { return statemap; } public void setstatemap(hashmultimap<string, string> statemap) { this.statemap = statemap; } }
i don't have solution (yet). here @ least clarifies problem. seems change made in java 7 build 15 , higher has broken method statement requires. if add exceptionlistener xmlencoder, gives better idea of how failing:
encoder.setexceptionlistener(new exceptionlistener() { @override public void exceptionthrown(exception e) { system.out.println("got exception. e=" + e); e.printstacktrace(); } });
you see full stacktrace then:
java.lang.exception: encoder: discarding statement hashmultimap.put(object, object); @ java.beans.encoder.writestatement(encoder.java:306) @ java.beans.xmlencoder.writestatement(xmlencoder.java:400) @ test2.xmlencodertest$custompersistencedelegate.initialize(xmlencodertest.java:83) @ java.beans.persistencedelegate.writeobject(persistencedelegate.java:118) @ java.beans.encoder.writeobject(encoder.java:74) @ java.beans.xmlencoder.writeobject(xmlencoder.java:327) @ java.beans.encoder.writeexpression(encoder.java:330) @ java.beans.xmlencoder.writeexpression(xmlencoder.java:454) @ java.beans.persistencedelegate.writeobject(persistencedelegate.java:115) @ java.beans.encoder.writeobject(encoder.java:74) @ java.beans.xmlencoder.writeobject(xmlencoder.java:327) @ java.beans.encoder.writeexpression(encoder.java:330) @ java.beans.xmlencoder.writeexpression(xmlencoder.java:454) @ java.beans.defaultpersistencedelegate.doproperty(defaultpersistencedelegate.java:194) @ java.beans.defaultpersistencedelegate.initbean(defaultpersistencedelegate.java:253) @ java.beans.defaultpersistencedelegate.initialize(defaultpersistencedelegate.java:400) @ java.beans.persistencedelegate.writeobject(persistencedelegate.java:118) @ java.beans.encoder.writeobject(encoder.java:74) @ java.beans.xmlencoder.writeobject(xmlencoder.java:327) @ java.beans.encoder.writeexpression(encoder.java:330) @ java.beans.xmlencoder.writeexpression(xmlencoder.java:454) @ java.beans.persistencedelegate.writeobject(persistencedelegate.java:115) @ java.beans.encoder.writeobject(encoder.java:74) @ java.beans.xmlencoder.writeobject(xmlencoder.java:327) @ java.beans.encoder.writeobject1(encoder.java:258) @ java.beans.encoder.clonestatement(encoder.java:271) @ java.beans.encoder.writestatement(encoder.java:301) @ java.beans.xmlencoder.writestatement(xmlencoder.java:400) @ java.beans.xmlencoder.writeobject(xmlencoder.java:330) ... caused by: java.lang.nosuchmethodexception: hashmultimap.put(object, object); @ java.beans.statement.invokeinternal(statement.java:313) @ java.beans.statement.access$000(statement.java:58) @ java.beans.statement$2.run(statement.java:185) @ java.security.accesscontroller.doprivileged(native method) @ java.beans.statement.invoke(statement.java:182) @ java.beans.statement.execute(statement.java:173) @ java.beans.encoder.writestatement(encoder.java:304) ... 51 more
the caused by section shows failed locate put method. looks me happens because can't match method signature more. fails in java beans methodfinder, since source code not included in jdk, couldn't track down enough.
if can find exact cause, update this. wanted provide more information in meantime.
update
i think it's bug in these later versions. here unit test exposes bug (or unexpected behavior) more directly. failure below happening in code:
@test public void testmethodfinder() throws exception { method m0 = methodfinder.findmethod(this.getclass(), "setup", new class<?>[0]); assertnotnull(m0); // okay, because method declared in type referenced method m = methodfinder.findmethod(multimap.class, "put", new class<?>[] { object.class, object.class }); assertnotnull(m); try { // fails, apparently because method not declared in subclass (is inherited parent class) method m2 = methodfinder.findmethod(hashmultimap.class, "put", new class<?>[] { object.class, object.class }); assertnotnull(m2); } catch (exception e) { system.out.println("got exception. e=" + e); } }
Comments
Post a Comment