Serialization patch and question
Jose Orlando Pereira
jop at di.uminho.pt
Wed Feb 3 07:48:01 PST 1999
Hi,
I've had some trouble with serialization on Kaffe (multiple refereces to
the same object, self referencing structures and readObject methods).
I've enclosed a patch that corrects all these problems and makes serialization
in Kaffe (almost) work for me.
A fourth problem (which produces "interesting" bugs) is exposed by
the enclosed program. In short, serialization incorrectly aliases
references because it uses a standard Hashtable, thus using equals()
and not ==.
As a side effect, there is a performance penalty in using hashCode()
and equals() instead of using directly the memory address, i.e.,
as default hashCode() and equals() methods for java.lang.Object do.
Before I start working on this, is there any chance of using default
Object.equals() and Object.hashCode() methods on an object of a derived
class, which redefines them as something else, besides "going native"?
Thanks in advance,
--
Jose Orlando Pereira
* mailto:jop at di.uminho.pt * http://gsd.di.uminho.pt/~jop *
-------------- next part --------------
diff -ru kaffe-snap/libraries/javalib/java/io/ObjectInputStream.java kaffe-snap-jop/libraries/javalib/java/io/ObjectInputStream.java
--- kaffe-snap/libraries/javalib/java/io/ObjectInputStream.java Wed Dec 9 23:20:11 1998
+++ kaffe-snap-jop/libraries/javalib/java/io/ObjectInputStream.java Tue Feb 2 18:39:06 1999
@@ -209,6 +209,8 @@
throw new StreamCorruptedException("expected class desc");
}
currObject = allocateNewObject(currStreamClass.clazz, null);
+ Integer key = new Integer(++nextKey);
+ objectsDone.put(key, currObject);
if ((currStreamClass.method & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0) {
try {
((Externalizable)currObject).readExternal(this);
@@ -217,7 +219,7 @@
}
}
else if ((currStreamClass.method & ObjectStreamConstants.SC_WRRD_METHODS) != 0) {
- invokeObjectReader(currObject, ObjectStreamClass.class);
+ invokeObjectReader(currObject, currObject.getClass());
}
else if ((currStreamClass.method & ObjectStreamConstants.SC_SERIALIZABLE) != 0) {
defaultReadObject();
@@ -240,6 +242,8 @@
case ObjectStreamConstants.TC_CLASSDESC:
ObjectStreamClass cls = new ObjectStreamClass();
currObject = (Object)cls;
+ Integer key = new Integer(++nextKey);
+ objectsDone.put(key, currObject);
invokeObjectReader(currObject, ObjectStreamClass.class);
cls.clazz = resolveClass(cls);
cls.buildFieldsAndOffset();
@@ -247,6 +251,8 @@
case ObjectStreamConstants.TC_STRING:
currObject = readUTF();
+ Integer key = new Integer(++nextKey);
+ objectsDone.put(key, currObject);
break;
case ObjectStreamConstants.TC_RESET:
@@ -259,10 +265,6 @@
default:
throw new StreamCorruptedException("unexpected token: " + tok);
}
-
- // Insert into hash table.
- Integer key = new Integer(++nextKey);
- objectsDone.put(currObject, key);
}
Object obj = currObject;
@@ -312,6 +314,8 @@
{
int len = readInt();
Object obj = allocateNewArray(currStreamClass.clazz, len);
+ Integer key = new Integer(++nextKey);
+ objectsDone.put(key, obj);
Class elem = currStreamClass.clazz.getComponentType();
if (elem == Object.class) {
-------------- next part --------------
// Demonstrates Serialization aliasing bug
import java.io.*;
class Pt implements Serializable {
public Pt(int x, int y) {
this.x=x;
this.y=y;
}
public void move(int dx, int dy) {
x+=dx;
y+=dy;
}
public boolean equals(Object obj) {
if (!(obj instanceof Pt))
return false;
Pt other=(Pt)obj;
return x==other.x && y==other.y;
}
public int hashCode() {
return x+y;
}
public String toString() {
return "("+x+", "+y+")";
}
private int x, y;
};
class Rect implements Serializable {
private Pt corner1, corner2;
public Rect(int x1, int y1, int x2, int y2) {
corner1=new Pt(x1, y1);
corner2=new Pt(x2, y2);
}
public void move(int dx, int dy) {
corner1.move(dx, dy);
corner2.move(dx, dy);
}
public String toString() {
return corner1.toString()+"-"+corner2;
}
}
public class Alias {
public static void main(String args[]) {
try {
Rect rect1=new Rect(1,1,1,1);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
oos.writeObject(rect1);
oos.flush();
byte data[]=baos.toByteArray();
System.out.println("Tam: "+data.length);
ByteArrayInputStream bais=new ByteArrayInputStream(data);
ObjectInputStream ois=new ObjectInputStream(bais);
Rect rect2=(Rect)ois.readObject();
System.out.println("rect1="+rect1+" rect2="+rect2);
rect1.move(2,2);
rect2.move(2,2);
System.out.println("rect1="+rect1+" rect2="+rect2);
} catch(Exception e) {
e.printStackTrace();
}
}
};
More information about the kaffe
mailing list