mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
ObjectOutputStream: use private writeObject() methods
The specification of the Java serialization demands that a private writeObject(ObjectOutputStream) method is used -- if it exists. In that case, ObjectOutputStream must not write the contents of the fields (called 'classdata[]' in the documentation) but offer that via the defaultWriteObject() method. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
parent
f3189bc79d
commit
931617a787
@ -13,6 +13,7 @@ package java.io;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
public class ObjectOutputStream extends OutputStream implements DataOutput {
|
public class ObjectOutputStream extends OutputStream implements DataOutput {
|
||||||
@ -192,7 +193,7 @@ public class ObjectOutputStream extends OutputStream implements DataOutput {
|
|||||||
throw new RuntimeException("Unhandled primitive type: " + type);
|
throw new RuntimeException("Unhandled primitive type: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void classDesc(Class clazz) throws IOException {
|
private void classDesc(Class clazz, int scFlags) throws IOException {
|
||||||
rawByte(TC_CLASSDESC);
|
rawByte(TC_CLASSDESC);
|
||||||
|
|
||||||
// class name
|
// class name
|
||||||
@ -207,7 +208,7 @@ public class ObjectOutputStream extends OutputStream implements DataOutput {
|
|||||||
rawLong(serialVersionUID);
|
rawLong(serialVersionUID);
|
||||||
|
|
||||||
// handle
|
// handle
|
||||||
rawByte(SC_SERIALIZABLE);
|
rawByte(SC_SERIALIZABLE | scFlags);
|
||||||
|
|
||||||
Field[] fields = getFields(clazz);
|
Field[] fields = getFields(clazz);
|
||||||
rawShort(fields.length);
|
rawShort(fields.length);
|
||||||
@ -292,13 +293,45 @@ public class ObjectOutputStream extends OutputStream implements DataOutput {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rawByte(TC_OBJECT);
|
rawByte(TC_OBJECT);
|
||||||
classDesc(o.getClass());
|
Method writeObject = getReadOrWriteMethod(o, "writeObject");
|
||||||
|
if (writeObject == null) {
|
||||||
|
classDesc(o.getClass(), 0);
|
||||||
|
defaultWriteObject(o);
|
||||||
|
} else try {
|
||||||
|
classDesc(o.getClass(), SC_WRITE_METHOD);
|
||||||
|
current = o;
|
||||||
|
writeObject.invoke(o, this);
|
||||||
|
current = null;
|
||||||
|
rawByte(TC_ENDBLOCKDATA);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Method getReadOrWriteMethod(Object o, String methodName) {
|
||||||
|
try {
|
||||||
|
Method method = o.getClass().getDeclaredMethod(methodName,
|
||||||
|
new Class[] { methodName.startsWith("write") ?
|
||||||
|
ObjectOutputStream.class : ObjectInputStream.class });
|
||||||
|
method.setAccessible(true);
|
||||||
|
int modifiers = method.getModifiers();
|
||||||
|
if ((modifiers & Modifier.STATIC) == 0 ||
|
||||||
|
(modifiers & Modifier.PRIVATE) != 0) {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException ignored) { }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object current;
|
||||||
|
|
||||||
|
public void defaultWriteObject() throws IOException {
|
||||||
|
defaultWriteObject(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void defaultWriteObject(Object o) throws IOException {
|
||||||
for (Field field : getFields(o.getClass())) {
|
for (Field field : getFields(o.getClass())) {
|
||||||
field(o, field);
|
field(o, field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void defaultWriteObject() throws IOException {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user