mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +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.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private void classDesc(Class clazz) throws IOException {
|
||||
private void classDesc(Class clazz, int scFlags) throws IOException {
|
||||
rawByte(TC_CLASSDESC);
|
||||
|
||||
// class name
|
||||
@ -207,7 +208,7 @@ public class ObjectOutputStream extends OutputStream implements DataOutput {
|
||||
rawLong(serialVersionUID);
|
||||
|
||||
// handle
|
||||
rawByte(SC_SERIALIZABLE);
|
||||
rawByte(SC_SERIALIZABLE | scFlags);
|
||||
|
||||
Field[] fields = getFields(clazz);
|
||||
rawShort(fields.length);
|
||||
@ -292,13 +293,45 @@ public class ObjectOutputStream extends OutputStream implements DataOutput {
|
||||
return;
|
||||
}
|
||||
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())) {
|
||||
field(o, field);
|
||||
}
|
||||
}
|
||||
|
||||
public void defaultWriteObject() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user