Oh。it's so great。From this mail I notice an effective ask, a good answer 。In the different companies to different people collaborate with each other to promote technology development I was a newer, I see the power of the community, it's great.
Charles may be come from oracle, Jimmy come from IBM in China, I come from China . Everyone can get benefits: Charles of the issue is resolved Jimmy received a feedback I learned more about how to participate in community. 2010/2/8 Jimmy,Jing Lv <firep...@gmail.com>: > Hi Charles, > > Sorry for late reply. > Thanks a lot for reporting this bug for Harmony and the testcase is > perfect. I've been reading the code, found it is mainly caused by the > Harmony ObjectStreamField does not resolve the primitive fields which are > declared in the serializable correctly and miss-initialize the string type. > I've got a quick fix, it works well on your testcase. I am running the full > testcases on it. Will commit soon if everything appears good. > Please review and tell if you have more questions. > > 2010/2/5 Charles Lamb <charles.l...@gmail.com> > >> Hello, >> >> I have submitted Jira HARMONY-6439 for this issue. Credit to my >> colleagues Mark Hayes and Haomian Wang for narrowing this down. >> >> Harmony object serialization has an initialization bug that causes >> NullPointerException when overriding the >> ObjectInputStream.readClassDescriptor and >> ObjectOutputStream.writeClassDescriptor methods, in order to store the >> ObjectStreamClass elsewhere. In Berkeley DB Java Edition, overriding >> these methods is necessary to store the ObjectStreamClass in a separate >> database, to avoid repeating it redundantly in every database record. >> This type of overriding is supported by the Java specification, and the >> problem does not occur in other Java class libraries (specifically, the >> bug does not occur on the Sun, IBM and BEA Java platforms). >> >> The attached test demonstrates the problem by simply serializing and >> deserializing an object to/from a byte array, when readClassDescriptor >> and writeClassDescriptor are overridden. A NullPointerException occurs >> because of an uninitialized field during the call to readObject. >> >> C:\temp>java -classpath . ClassDescriptorOverrideBug >> java.lang.NullPointerException >> at java.io.ObjectStreamField.resolve(ObjectStreamField.java:336) >> at >> java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1838) >> at >> java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:799) >> at >> java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2039) >> at >> >> java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:902) >> at >> java.io.ObjectInputStream.readObject(ObjectInputStream.java:2251) >> at >> java.io.ObjectInputStream.readObject(ObjectInputStream.java:2208) >> at >> ClassDescriptorOverrideBug.doTest(ClassDescriptorOverrideBug.java:49) >> at >> ClassDescriptorOverrideBug.main(ClassDescriptorOverrideBug.java:29) >> >> Note that this problem only occurs when primitive fields are declared in >> the serializable class. >> >> A workaround for this bug is to serialize and deserialize the >> ObjectStreamClass before it is used. Apparently deserialization causes >> initialization to occur correctly. >> >> >> >> import java.io.ByteArrayInputStream; >> import java.io.ByteArrayOutputStream; >> import java.io.InputStream; >> import java.io.IOException; >> import java.io.ObjectInputStream; >> import java.io.ObjectOutputStream; >> import java.io.ObjectStreamClass; >> import java.io.OutputStream; >> import java.io.Serializable; >> import java.util.HashMap; >> import java.util.Map; >> >> /** >> * Demonstrates a Harmony bug in Java serialization, where overriding the >> * ObjectInputStream.readClassDescriptor and >> * ObjectOutputStream.writeClassDescriptor methods, in order to store the >> * ObjectStreamClass elsewhere, causes a NullPointerException. >> */ >> public class ClassDescriptorOverrideBug { >> >> private final Map<Integer, ObjectStreamClass> idToDescMap = >> new HashMap<Integer, ObjectStreamClass>(); >> private final Map<String, Integer> nameToIdMap = >> new HashMap<String, Integer>(); >> private int nextId = 1; >> >> public static void main(String argv[]) { >> try { >> new ClassDescriptorOverrideBug().doTest(); >> System.out.println("SUCCESS"); >> System.exit(0); >> } catch (Exception e) { >> e.printStackTrace(); >> System.exit(1); >> } >> } >> >> /* Write/serialize and read/de-serialize an object. */ >> void doTest() >> throws IOException, ClassNotFoundException { >> >> final ByteArrayOutputStream baos = new ByteArrayOutputStream(); >> final MyObjectOutputStream oos = new MyObjectOutputStream(baos); >> oos.writeObject(new Data()); >> final byte[] bytes = baos.toByteArray(); >> final ByteArrayInputStream bais = new ByteArrayInputStream(bytes); >> final MyObjectInputStream ois = new MyObjectInputStream(bais); >> /* NullPointerException is thrown by the readObject call below. */ >> ois.readObject(); >> } >> >> /* Primitive fields are necessary to cause the NullPointerException. */ >> static class Data implements Serializable { >> String field1 = "field1"; >> String field2 = "field2"; >> int field3 = 333; >> int field4 = 444; >> String field5 = "field5"; >> } >> >> /* Overrides writeClassDescriptor to store ObjectStreamClass in map. */ >> class MyObjectOutputStream extends ObjectOutputStream { >> >> MyObjectOutputStream(OutputStream out) >> throws IOException { >> >> super(out); >> } >> >> �...@override >> protected void writeClassDescriptor(ObjectStreamClass desc) >> throws IOException { >> >> final String className = desc.getName(); >> final int id; >> if (nameToIdMap.containsKey(className)) { >> /* Known class: get ID from map. */ >> id = nameToIdMap.get(className); >> } else { >> /* New class: assign ID and store in maps. */ >> id = nextId; >> nextId += 1; >> idToDescMap.put(id, desc); >> nameToIdMap.put(className, id); >> } >> /* Write ID of ObjectStreamClass. */ >> writeInt(id); >> } >> } >> >> /* Overrides readClassDescriptor to get ObjectStreamClass from map. */ >> class MyObjectInputStream extends ObjectInputStream { >> >> MyObjectInputStream(InputStream in) >> throws IOException { >> >> super(in); >> } >> >> �...@override >> protected ObjectStreamClass readClassDescriptor() >> throws IOException, ClassNotFoundException { >> >> /* Read the ID and get the ObjectStreamClass from a map. */ >> final int id = readInt(); >> final ObjectStreamClass desc = idToDescMap.get(id); >> if (desc == null) { >> throw new ClassNotFoundException("id not found: " + id); >> } >> return desc; >> } >> } >> } >> >> >> >> > > > -- > > Best Regards! > > Jimmy, Jing Lv > China Software Development Lab, IBM >