-
Bug
-
Resolution: Fixed
-
P3
-
1.1.4
-
1.1.6
-
sparc
-
solaris_2.6
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2018069 | 1.2.0 | Joe Fialli | P3 | Resolved | Fixed | 1.2beta3 |
Once an object has been added to an object output stream's validation vector, there doesn't seem to be a way to remove it. The comments for doValidations() appear to imply that once executed, the validation should be "cleaned up".
Once the object has been registered, it is called each time
ObjectOutputSTream.readObject() returns an object, any object, to the top-level caller. Is that the intended behaviour?
Since registerValidation() is invoked from within an object's readObject(),
one would expect that you're only registering interest for validating
that particular object, not all objects read from the stream.
Here's a test program that shows the validation object being called 2 times, once for the object it was interested in, and once for another object read from the same stream.
import java.io.*;
import java.util.Date;
class Main {
public static void main(String[] args) {
try {
// Write class out
FileOutputStream f = new FileOutputStream("Class1.ser");
ObjectOutput out = new ObjectOutputStream(f);
Class1 c1 = new Class1(11, 22);
out.writeObject(c1);
out.writeObject(new Date());
out.flush();
out.close();
// Read it back
FileInputStream f2 = new FileInputStream("Class1.ser");
ObjectInputStream in = new ObjectInputStream(f2);
Class1 cc1 = (Class1) in.readObject();
System.out.println("date: " + in.readObject());
in.close();
System.out.println(cc1.a + " " + cc1.b);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Class1 implements Serializable, ObjectInputValidation {
int a, b;
public Class1(int aa, int bb) {
a = aa;
b = bb;
}
public void validateObject() throws InvalidObjectException {
System.out.println("Validating object");
if (a > b) {
throw new InvalidObjectException("Fields cannot be negative");
}
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.registerValidation(this, 1);
in.defaultReadObject();
}
}
=========================================
Actually the instance of Class1 is validated each time a top-level
object is read from the stream. Here is the output of the test
case when the source is annotated to print out the "toString" of
the object being validated.
joef/scarry>java Validate
Validating object:Class1@8f9bb3ff
Validating object:Class1@8f9bb3ff
date: Mon Nov 24 14:24:47 EST 1997
11 22
Thus, the correct way to describe this is that once an object is registered
for validation, it will be validate each time a top-level, not recursive,
readObject() occurs.
joseph.fialli@East 1997-11-24
Once the object has been registered, it is called each time
ObjectOutputSTream.readObject() returns an object, any object, to the top-level caller. Is that the intended behaviour?
Since registerValidation() is invoked from within an object's readObject(),
one would expect that you're only registering interest for validating
that particular object, not all objects read from the stream.
Here's a test program that shows the validation object being called 2 times, once for the object it was interested in, and once for another object read from the same stream.
import java.io.*;
import java.util.Date;
class Main {
public static void main(String[] args) {
try {
// Write class out
FileOutputStream f = new FileOutputStream("Class1.ser");
ObjectOutput out = new ObjectOutputStream(f);
Class1 c1 = new Class1(11, 22);
out.writeObject(c1);
out.writeObject(new Date());
out.flush();
out.close();
// Read it back
FileInputStream f2 = new FileInputStream("Class1.ser");
ObjectInputStream in = new ObjectInputStream(f2);
Class1 cc1 = (Class1) in.readObject();
System.out.println("date: " + in.readObject());
in.close();
System.out.println(cc1.a + " " + cc1.b);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Class1 implements Serializable, ObjectInputValidation {
int a, b;
public Class1(int aa, int bb) {
a = aa;
b = bb;
}
public void validateObject() throws InvalidObjectException {
System.out.println("Validating object");
if (a > b) {
throw new InvalidObjectException("Fields cannot be negative");
}
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.registerValidation(this, 1);
in.defaultReadObject();
}
}
=========================================
Actually the instance of Class1 is validated each time a top-level
object is read from the stream. Here is the output of the test
case when the source is annotated to print out the "toString" of
the object being validated.
joef/scarry>java Validate
Validating object:Class1@8f9bb3ff
Validating object:Class1@8f9bb3ff
date: Mon Nov 24 14:24:47 EST 1997
11 22
Thus, the correct way to describe this is that once an object is registered
for validation, it will be validate each time a top-level, not recursive,
readObject() occurs.
joseph.fialli@East 1997-11-24
- backported by
-
JDK-2018069 ObjectInputValidations incorrectly get run multiple times.
- Resolved