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