提交 0cc59e1d 编写于 作者: I igerasim

8103671: More objective stream classes

Reviewed-by: rriggs, igerasim
上级 17fc9f84
...@@ -189,6 +189,9 @@ public class ObjectStreamClass implements Serializable { ...@@ -189,6 +189,9 @@ public class ObjectStreamClass implements Serializable {
/** superclass descriptor appearing in stream */ /** superclass descriptor appearing in stream */
private ObjectStreamClass superDesc; private ObjectStreamClass superDesc;
/** true if, and only if, the object has been correctly initialized */
private boolean initialized;
/** /**
* Initializes native code. * Initializes native code.
*/ */
...@@ -266,6 +269,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -266,6 +269,7 @@ public class ObjectStreamClass implements Serializable {
if (cl == null) { if (cl == null) {
return null; return null;
} }
requireInitialized();
if (System.getSecurityManager() != null) { if (System.getSecurityManager() != null) {
Class<?> caller = Reflection.getCallerClass(); Class<?> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), cl.getClassLoader())) { if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), cl.getClassLoader())) {
...@@ -533,6 +537,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -533,6 +537,7 @@ public class ObjectStreamClass implements Serializable {
name, "unmatched serializable field(s) declared"); name, "unmatched serializable field(s) declared");
} }
} }
initialized = true;
} }
/** /**
...@@ -550,6 +555,14 @@ public class ObjectStreamClass implements Serializable { ...@@ -550,6 +555,14 @@ public class ObjectStreamClass implements Serializable {
ObjectStreamClass superDesc) ObjectStreamClass superDesc)
throws InvalidClassException throws InvalidClassException
{ {
ObjectStreamClass osc = null;
if (cl != null) {
osc = lookup(cl, true);
if (!osc.isProxy) {
throw new InvalidClassException(
"cannot bind proxy descriptor to a non-proxy class");
}
}
this.cl = cl; this.cl = cl;
this.resolveEx = resolveEx; this.resolveEx = resolveEx;
this.superDesc = superDesc; this.superDesc = superDesc;
...@@ -557,21 +570,17 @@ public class ObjectStreamClass implements Serializable { ...@@ -557,21 +570,17 @@ public class ObjectStreamClass implements Serializable {
serializable = true; serializable = true;
suid = Long.valueOf(0); suid = Long.valueOf(0);
fields = NO_FIELDS; fields = NO_FIELDS;
if (osc != null) {
if (cl != null) { localDesc = osc;
localDesc = lookup(cl, true);
if (!localDesc.isProxy) {
throw new InvalidClassException(
"cannot bind proxy descriptor to a non-proxy class");
}
name = localDesc.name; name = localDesc.name;
externalizable = localDesc.externalizable; externalizable = localDesc.externalizable;
cons = localDesc.cons;
writeReplaceMethod = localDesc.writeReplaceMethod; writeReplaceMethod = localDesc.writeReplaceMethod;
readResolveMethod = localDesc.readResolveMethod; readResolveMethod = localDesc.readResolveMethod;
deserializeEx = localDesc.deserializeEx; deserializeEx = localDesc.deserializeEx;
cons = localDesc.cons;
} }
fieldRefl = getReflector(fields, localDesc); fieldRefl = getReflector(fields, localDesc);
initialized = true;
} }
/** /**
...@@ -583,68 +592,69 @@ public class ObjectStreamClass implements Serializable { ...@@ -583,68 +592,69 @@ public class ObjectStreamClass implements Serializable {
ObjectStreamClass superDesc) ObjectStreamClass superDesc)
throws InvalidClassException throws InvalidClassException
{ {
this.cl = cl; long suid = Long.valueOf(model.getSerialVersionUID());
this.resolveEx = resolveEx; ObjectStreamClass osc = null;
this.superDesc = superDesc;
name = model.name;
suid = Long.valueOf(model.getSerialVersionUID());
isProxy = false;
isEnum = model.isEnum;
serializable = model.serializable;
externalizable = model.externalizable;
hasBlockExternalData = model.hasBlockExternalData;
hasWriteObjectData = model.hasWriteObjectData;
fields = model.fields;
primDataSize = model.primDataSize;
numObjFields = model.numObjFields;
if (cl != null) { if (cl != null) {
localDesc = lookup(cl, true); osc = lookup(cl, true);
if (localDesc.isProxy) { if (osc.isProxy) {
throw new InvalidClassException( throw new InvalidClassException(
"cannot bind non-proxy descriptor to a proxy class"); "cannot bind non-proxy descriptor to a proxy class");
} }
if (isEnum != localDesc.isEnum) { if (model.isEnum != osc.isEnum) {
throw new InvalidClassException(isEnum ? throw new InvalidClassException(model.isEnum ?
"cannot bind enum descriptor to a non-enum class" : "cannot bind enum descriptor to a non-enum class" :
"cannot bind non-enum descriptor to an enum class"); "cannot bind non-enum descriptor to an enum class");
} }
if (serializable == localDesc.serializable && if (model.serializable == osc.serializable &&
!cl.isArray() && !cl.isArray() &&
suid.longValue() != localDesc.getSerialVersionUID()) suid != osc.getSerialVersionUID()) {
{ throw new InvalidClassException(osc.name,
throw new InvalidClassException(localDesc.name,
"local class incompatible: " + "local class incompatible: " +
"stream classdesc serialVersionUID = " + suid + "stream classdesc serialVersionUID = " + suid +
", local class serialVersionUID = " + ", local class serialVersionUID = " +
localDesc.getSerialVersionUID()); osc.getSerialVersionUID());
} }
if (!classNamesEqual(name, localDesc.name)) { if (!classNamesEqual(model.name, osc.name)) {
throw new InvalidClassException(localDesc.name, throw new InvalidClassException(osc.name,
"local class name incompatible with stream class " + "local class name incompatible with stream class " +
"name \"" + name + "\""); "name \"" + model.name + "\"");
} }
if (!isEnum) { if (!model.isEnum) {
if ((serializable == localDesc.serializable) && if ((model.serializable == osc.serializable) &&
(externalizable != localDesc.externalizable)) (model.externalizable != osc.externalizable)) {
{ throw new InvalidClassException(osc.name,
throw new InvalidClassException(localDesc.name,
"Serializable incompatible with Externalizable"); "Serializable incompatible with Externalizable");
} }
if ((serializable != localDesc.serializable) || if ((model.serializable != osc.serializable) ||
(externalizable != localDesc.externalizable) || (model.externalizable != osc.externalizable) ||
!(serializable || externalizable)) !(model.serializable || model.externalizable)) {
{
deserializeEx = new ExceptionInfo( deserializeEx = new ExceptionInfo(
localDesc.name, "class invalid for deserialization"); osc.name, "class invalid for deserialization");
}
} }
} }
cons = localDesc.cons; this.cl = cl;
this.resolveEx = resolveEx;
this.superDesc = superDesc;
name = model.name;
this.suid = suid;
isProxy = false;
isEnum = model.isEnum;
serializable = model.serializable;
externalizable = model.externalizable;
hasBlockExternalData = model.hasBlockExternalData;
hasWriteObjectData = model.hasWriteObjectData;
fields = model.fields;
primDataSize = model.primDataSize;
numObjFields = model.numObjFields;
if (osc != null) {
localDesc = osc;
writeObjectMethod = localDesc.writeObjectMethod; writeObjectMethod = localDesc.writeObjectMethod;
readObjectMethod = localDesc.readObjectMethod; readObjectMethod = localDesc.readObjectMethod;
readObjectNoDataMethod = localDesc.readObjectNoDataMethod; readObjectNoDataMethod = localDesc.readObjectNoDataMethod;
...@@ -653,10 +663,13 @@ public class ObjectStreamClass implements Serializable { ...@@ -653,10 +663,13 @@ public class ObjectStreamClass implements Serializable {
if (deserializeEx == null) { if (deserializeEx == null) {
deserializeEx = localDesc.deserializeEx; deserializeEx = localDesc.deserializeEx;
} }
cons = localDesc.cons;
} }
fieldRefl = getReflector(fields, localDesc); fieldRefl = getReflector(fields, localDesc);
// reassign to matched fields so as to reflect local unshared settings // reassign to matched fields so as to reflect local unshared settings
fields = fieldRefl.getFields(); fields = fieldRefl.getFields();
initialized = true;
} }
/** /**
...@@ -758,12 +771,21 @@ public class ObjectStreamClass implements Serializable { ...@@ -758,12 +771,21 @@ public class ObjectStreamClass implements Serializable {
return resolveEx; return resolveEx;
} }
/**
* Throws InternalError if not initialized.
*/
private final void requireInitialized() {
if (!initialized)
throw new InternalError("Unexpected call when not initialized");
}
/** /**
* Throws an InvalidClassException if object instances referencing this * Throws an InvalidClassException if object instances referencing this
* class descriptor should not be allowed to deserialize. This method does * class descriptor should not be allowed to deserialize. This method does
* not apply to deserialization of enum constants. * not apply to deserialization of enum constants.
*/ */
void checkDeserialize() throws InvalidClassException { void checkDeserialize() throws InvalidClassException {
requireInitialized();
if (deserializeEx != null) { if (deserializeEx != null) {
throw deserializeEx.newInvalidClassException(); throw deserializeEx.newInvalidClassException();
} }
...@@ -775,6 +797,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -775,6 +797,7 @@ public class ObjectStreamClass implements Serializable {
* not apply to serialization of enum constants. * not apply to serialization of enum constants.
*/ */
void checkSerialize() throws InvalidClassException { void checkSerialize() throws InvalidClassException {
requireInitialized();
if (serializeEx != null) { if (serializeEx != null) {
throw serializeEx.newInvalidClassException(); throw serializeEx.newInvalidClassException();
} }
...@@ -788,6 +811,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -788,6 +811,7 @@ public class ObjectStreamClass implements Serializable {
* does not apply to deserialization of enum constants. * does not apply to deserialization of enum constants.
*/ */
void checkDefaultSerialize() throws InvalidClassException { void checkDefaultSerialize() throws InvalidClassException {
requireInitialized();
if (defaultSerializeEx != null) { if (defaultSerializeEx != null) {
throw defaultSerializeEx.newInvalidClassException(); throw defaultSerializeEx.newInvalidClassException();
} }
...@@ -799,6 +823,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -799,6 +823,7 @@ public class ObjectStreamClass implements Serializable {
* of the subclass descriptor's bound class. * of the subclass descriptor's bound class.
*/ */
ObjectStreamClass getSuperDesc() { ObjectStreamClass getSuperDesc() {
requireInitialized();
return superDesc; return superDesc;
} }
...@@ -809,6 +834,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -809,6 +834,7 @@ public class ObjectStreamClass implements Serializable {
* associated with this descriptor. * associated with this descriptor.
*/ */
ObjectStreamClass getLocalDesc() { ObjectStreamClass getLocalDesc() {
requireInitialized();
return localDesc; return localDesc;
} }
...@@ -819,6 +845,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -819,6 +845,7 @@ public class ObjectStreamClass implements Serializable {
* returned. * returned.
*/ */
ObjectStreamField[] getFields(boolean copy) { ObjectStreamField[] getFields(boolean copy) {
requireInitialized();
return copy ? fields.clone() : fields; return copy ? fields.clone() : fields;
} }
...@@ -829,6 +856,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -829,6 +856,7 @@ public class ObjectStreamClass implements Serializable {
* types only. Returns matching field, or null if no match found. * types only. Returns matching field, or null if no match found.
*/ */
ObjectStreamField getField(String name, Class<?> type) { ObjectStreamField getField(String name, Class<?> type) {
requireInitialized();
for (int i = 0; i < fields.length; i++) { for (int i = 0; i < fields.length; i++) {
ObjectStreamField f = fields[i]; ObjectStreamField f = fields[i];
if (f.getName().equals(name)) { if (f.getName().equals(name)) {
...@@ -851,6 +879,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -851,6 +879,7 @@ public class ObjectStreamClass implements Serializable {
* otherwise. * otherwise.
*/ */
boolean isProxy() { boolean isProxy() {
requireInitialized();
return isProxy; return isProxy;
} }
...@@ -859,6 +888,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -859,6 +888,7 @@ public class ObjectStreamClass implements Serializable {
* otherwise. * otherwise.
*/ */
boolean isEnum() { boolean isEnum() {
requireInitialized();
return isEnum; return isEnum;
} }
...@@ -867,6 +897,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -867,6 +897,7 @@ public class ObjectStreamClass implements Serializable {
* otherwise. * otherwise.
*/ */
boolean isExternalizable() { boolean isExternalizable() {
requireInitialized();
return externalizable; return externalizable;
} }
...@@ -875,6 +906,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -875,6 +906,7 @@ public class ObjectStreamClass implements Serializable {
* otherwise. * otherwise.
*/ */
boolean isSerializable() { boolean isSerializable() {
requireInitialized();
return serializable; return serializable;
} }
...@@ -883,6 +915,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -883,6 +915,7 @@ public class ObjectStreamClass implements Serializable {
* has written its data in 1.2 (block data) format, false otherwise. * has written its data in 1.2 (block data) format, false otherwise.
*/ */
boolean hasBlockExternalData() { boolean hasBlockExternalData() {
requireInitialized();
return hasBlockExternalData; return hasBlockExternalData;
} }
...@@ -892,6 +925,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -892,6 +925,7 @@ public class ObjectStreamClass implements Serializable {
* writeObject() method, false otherwise. * writeObject() method, false otherwise.
*/ */
boolean hasWriteObjectData() { boolean hasWriteObjectData() {
requireInitialized();
return hasWriteObjectData; return hasWriteObjectData;
} }
...@@ -903,6 +937,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -903,6 +937,7 @@ public class ObjectStreamClass implements Serializable {
* accessible no-arg constructor. Otherwise, returns false. * accessible no-arg constructor. Otherwise, returns false.
*/ */
boolean isInstantiable() { boolean isInstantiable() {
requireInitialized();
return (cons != null); return (cons != null);
} }
...@@ -912,6 +947,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -912,6 +947,7 @@ public class ObjectStreamClass implements Serializable {
* returns false. * returns false.
*/ */
boolean hasWriteObjectMethod() { boolean hasWriteObjectMethod() {
requireInitialized();
return (writeObjectMethod != null); return (writeObjectMethod != null);
} }
...@@ -921,6 +957,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -921,6 +957,7 @@ public class ObjectStreamClass implements Serializable {
* returns false. * returns false.
*/ */
boolean hasReadObjectMethod() { boolean hasReadObjectMethod() {
requireInitialized();
return (readObjectMethod != null); return (readObjectMethod != null);
} }
...@@ -930,6 +967,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -930,6 +967,7 @@ public class ObjectStreamClass implements Serializable {
* Otherwise, returns false. * Otherwise, returns false.
*/ */
boolean hasReadObjectNoDataMethod() { boolean hasReadObjectNoDataMethod() {
requireInitialized();
return (readObjectNoDataMethod != null); return (readObjectNoDataMethod != null);
} }
...@@ -938,6 +976,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -938,6 +976,7 @@ public class ObjectStreamClass implements Serializable {
* defines a conformant writeReplace method. Otherwise, returns false. * defines a conformant writeReplace method. Otherwise, returns false.
*/ */
boolean hasWriteReplaceMethod() { boolean hasWriteReplaceMethod() {
requireInitialized();
return (writeReplaceMethod != null); return (writeReplaceMethod != null);
} }
...@@ -946,6 +985,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -946,6 +985,7 @@ public class ObjectStreamClass implements Serializable {
* defines a conformant readResolve method. Otherwise, returns false. * defines a conformant readResolve method. Otherwise, returns false.
*/ */
boolean hasReadResolveMethod() { boolean hasReadResolveMethod() {
requireInitialized();
return (readResolveMethod != null); return (readResolveMethod != null);
} }
...@@ -962,6 +1002,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -962,6 +1002,7 @@ public class ObjectStreamClass implements Serializable {
throws InstantiationException, InvocationTargetException, throws InstantiationException, InvocationTargetException,
UnsupportedOperationException UnsupportedOperationException
{ {
requireInitialized();
if (cons != null) { if (cons != null) {
try { try {
return cons.newInstance(); return cons.newInstance();
...@@ -983,6 +1024,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -983,6 +1024,7 @@ public class ObjectStreamClass implements Serializable {
void invokeWriteObject(Object obj, ObjectOutputStream out) void invokeWriteObject(Object obj, ObjectOutputStream out)
throws IOException, UnsupportedOperationException throws IOException, UnsupportedOperationException
{ {
requireInitialized();
if (writeObjectMethod != null) { if (writeObjectMethod != null) {
try { try {
writeObjectMethod.invoke(obj, new Object[]{ out }); writeObjectMethod.invoke(obj, new Object[]{ out });
...@@ -1012,6 +1054,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -1012,6 +1054,7 @@ public class ObjectStreamClass implements Serializable {
throws ClassNotFoundException, IOException, throws ClassNotFoundException, IOException,
UnsupportedOperationException UnsupportedOperationException
{ {
requireInitialized();
if (readObjectMethod != null) { if (readObjectMethod != null) {
try { try {
readObjectMethod.invoke(obj, new Object[]{ in }); readObjectMethod.invoke(obj, new Object[]{ in });
...@@ -1042,6 +1085,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -1042,6 +1085,7 @@ public class ObjectStreamClass implements Serializable {
void invokeReadObjectNoData(Object obj) void invokeReadObjectNoData(Object obj)
throws IOException, UnsupportedOperationException throws IOException, UnsupportedOperationException
{ {
requireInitialized();
if (readObjectNoDataMethod != null) { if (readObjectNoDataMethod != null) {
try { try {
readObjectNoDataMethod.invoke(obj, (Object[]) null); readObjectNoDataMethod.invoke(obj, (Object[]) null);
...@@ -1070,6 +1114,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -1070,6 +1114,7 @@ public class ObjectStreamClass implements Serializable {
Object invokeWriteReplace(Object obj) Object invokeWriteReplace(Object obj)
throws IOException, UnsupportedOperationException throws IOException, UnsupportedOperationException
{ {
requireInitialized();
if (writeReplaceMethod != null) { if (writeReplaceMethod != null) {
try { try {
return writeReplaceMethod.invoke(obj, (Object[]) null); return writeReplaceMethod.invoke(obj, (Object[]) null);
...@@ -1099,6 +1144,7 @@ public class ObjectStreamClass implements Serializable { ...@@ -1099,6 +1144,7 @@ public class ObjectStreamClass implements Serializable {
Object invokeReadResolve(Object obj) Object invokeReadResolve(Object obj)
throws IOException, UnsupportedOperationException throws IOException, UnsupportedOperationException
{ {
requireInitialized();
if (readResolveMethod != null) { if (readResolveMethod != null) {
try { try {
return readResolveMethod.invoke(obj, (Object[]) null); return readResolveMethod.invoke(obj, (Object[]) null);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册