Just one addendum... "When you asked me long ago to consider using the micro-container's reflection metadata to serialization, I didn't do it because serialization is something totally different in terms of reflection's metadatas. Hibernate and MicroContainer deals with Properties collections, while Reflection deals with properties (private and final private), and some other weird definitions like object replacement, private readObject, private writeObject, and other things like that.
But if you provide an alternative way to access fields (I was actually looking for one :-)), I can definitely extend the metadata to support this." > That is the reason a serializable class must have a noargs constructor. Actually an externalizable needs a noarg constructor. A regular serializable class don't. Serialization needs hooks to change final fields, as a ghost constructor is created, calling the non-serializable's super class constructor. (Object() in the worse case), and after its creationg the fields are changed (final and regular fields). Sun's implementation uses sun.misc.Unsafe to do this job. I do the same job through FieldsManager, and I delegate to regular reflection (on JVM 1.5 you can change a final field if you set accessible to true, and if the SecurityManger allows you to do that) or falling back into Unsafe if available and regular reflection doesn't work. (in other words, I will use sun.misc.Unsafe if JVM 1.4) I have tested this mechanism using Sun, BEA and IBM's JVM. If you look at this following example, you don't have a default constructor, and the final field is changed on the serialization. The constructor(int) here is not used to change finalValue, as any exception was generated. import java.util.Random; import java.io.*; public class TestSer implements java.io.Serializable { public static boolean PRINT_MESSAGE=false; private final int finalValue; private String strValue; public TestSer(int value) { if (PRINT_MESSAGE) { throw new RuntimeException("This constructor shouldn't be called now"); } this.finalValue=value; this.strValue = "Some value=" + finalValue; } public String toString() { return "finalValue = " + finalValue + " and strValue=" + strValue; } public static void main(String arg[]) { try { TestSer ser = new TestSer(1000); TestSer.PRINT_MESSAGE=true; ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(ser); out.flush(); ByteArrayInputStream byteInp = new ByteArrayInputStream(byteOut.toByteArray()); ObjectInputStream inp = new ObjectInputStream(byteInp); TestSer ser2=(TestSer) inp.readObject(); System.out.println("ser1=[" + ser + "] and ser=[" + ser2 + "]"); } catch (Throwable e) { e.printStackTrace(); } } } The only output I got was: ser1=[finalValue = 1000 and strValue=Some value=1000] and ser=[finalValue = 1000 and strValue=Some value=1000] ------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Do you grep through log files for problems? Stop! Download the new AJAX search engine that makes searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! http://sel.as-us.falkag.net/sel?cmd=lnk&kid3432&bid#0486&dat1642 _______________________________________________ JBoss-Development mailing list JBoss-Development@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jboss-development