7110700: Enhance exception throwing mechanism in ObjectStreamClass
Reviewed-by: dmeetry, hawtin
--- a/jdk/src/share/classes/java/io/ObjectStreamClass.java Wed Oct 26 14:00:18 2011 +0400
+++ b/jdk/src/share/classes/java/io/ObjectStreamClass.java Fri Nov 11 15:22:11 2011 -0800
@@ -123,14 +123,39 @@
*/
private boolean hasBlockExternalData = true;
+ /**
+ * Contains information about InvalidClassException instances to be thrown
+ * when attempting operations on an invalid class. Note that instances of
+ * this class are immutable and are potentially shared among
+ * ObjectStreamClass instances.
+ */
+ private static class ExceptionInfo {
+ private final String className;
+ private final String message;
+
+ ExceptionInfo(String cn, String msg) {
+ className = cn;
+ message = msg;
+ }
+
+ /**
+ * Returns (does not throw) an InvalidClassException instance created
+ * from the information in this object, suitable for being thrown by
+ * the caller.
+ */
+ InvalidClassException newInvalidClassException() {
+ return new InvalidClassException(className, message);
+ }
+ }
+
/** exception (if any) thrown while attempting to resolve class */
private ClassNotFoundException resolveEx;
/** exception (if any) to throw if non-enum deserialization attempted */
- private InvalidClassException deserializeEx;
+ private ExceptionInfo deserializeEx;
/** exception (if any) to throw if non-enum serialization attempted */
- private InvalidClassException serializeEx;
+ private ExceptionInfo serializeEx;
/** exception (if any) to throw if default serialization attempted */
- private InvalidClassException defaultSerializeEx;
+ private ExceptionInfo defaultSerializeEx;
/** serializable fields */
private ObjectStreamField[] fields;
@@ -444,7 +469,8 @@
fields = getSerialFields(cl);
computeFieldOffsets();
} catch (InvalidClassException e) {
- serializeEx = deserializeEx = e;
+ serializeEx = deserializeEx =
+ new ExceptionInfo(e.classname, e.getMessage());
fields = NO_FIELDS;
}
@@ -483,15 +509,14 @@
if (deserializeEx == null) {
if (isEnum) {
- deserializeEx = new InvalidClassException(name, "enum type");
+ deserializeEx = new ExceptionInfo(name, "enum type");
} else if (cons == null) {
- deserializeEx = new InvalidClassException(
- name, "no valid constructor");
+ deserializeEx = new ExceptionInfo(name, "no valid constructor");
}
}
for (int i = 0; i < fields.length; i++) {
if (fields[i].getField() == null) {
- defaultSerializeEx = new InvalidClassException(
+ defaultSerializeEx = new ExceptionInfo(
name, "unmatched serializable field(s) declared");
}
}
@@ -601,8 +626,8 @@
(externalizable != localDesc.externalizable) ||
!(serializable || externalizable))
{
- deserializeEx = new InvalidClassException(localDesc.name,
- "class invalid for deserialization");
+ deserializeEx = new ExceptionInfo(
+ localDesc.name, "class invalid for deserialization");
}
}
@@ -727,11 +752,7 @@
*/
void checkDeserialize() throws InvalidClassException {
if (deserializeEx != null) {
- InvalidClassException ice =
- new InvalidClassException(deserializeEx.classname,
- deserializeEx.getMessage());
- ice.initCause(deserializeEx);
- throw ice;
+ throw deserializeEx.newInvalidClassException();
}
}
@@ -742,11 +763,7 @@
*/
void checkSerialize() throws InvalidClassException {
if (serializeEx != null) {
- InvalidClassException ice =
- new InvalidClassException(serializeEx.classname,
- serializeEx.getMessage());
- ice.initCause(serializeEx);
- throw ice;
+ throw serializeEx.newInvalidClassException();
}
}
@@ -759,11 +776,7 @@
*/
void checkDefaultSerialize() throws InvalidClassException {
if (defaultSerializeEx != null) {
- InvalidClassException ice =
- new InvalidClassException(defaultSerializeEx.classname,
- defaultSerializeEx.getMessage());
- ice.initCause(defaultSerializeEx);
- throw ice;
+ throw defaultSerializeEx.newInvalidClassException();
}
}
--- a/jdk/test/java/io/Serializable/expectedStackTrace/ExpectedStackTrace.java Wed Oct 26 14:00:18 2011 +0400
+++ b/jdk/test/java/io/Serializable/expectedStackTrace/ExpectedStackTrace.java Fri Nov 11 15:22:11 2011 -0800
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 6317435
+ * @bug 6317435 7068148
* @summary Verify that stack trace contains a proper cause of
* InvalidClassException (methods: checkSerialize,
* checkDeserialize or checkDefaultSerialize)
@@ -59,7 +59,7 @@
private static final String SER_METHOD_NAME = "checkSerializable";
public static final void main(String[] args) throws Exception {
- System.err.println("\nRegression test for CR6317435");
+ System.err.println("\nRegression test for CRs 6317435, 7068148");
checkSerializable(getObject());
}
@@ -99,9 +99,11 @@
}
}
if (found) {
- System.err.println("\nTEST PASSED");
+ if (ex.getCause() != null) {
+ throw new Error("\nTest for CR 7068148 FAILED");
+ }
} else {
- throw new Error();
+ throw new Error("\nTest for CR 6317435 FAILED");
}
}
}