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 : > 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 > >> 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 idToDescMap = >>        new HashMap(); >>    private final Map nameToIdMap = >>        new HashMap(); >>    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 >