Hello all!
Why not fix bug DIRMINA-627? Mina can't serialize all instances of
java.lang.Class are serializable both in 1.1.7 stable or 2.0.0-M6 unstable.This
bug can be easly to fixed, and I have added a comment in the issue report. But
it was not fixed in every released versions. I really need this feature, and I
have to modify mina source code in my project. Here is my solution:
Serializable object can be divide into three types:
a)java.lang.Class instances representing classes that are not serializable
b)Primitive objects
c)Other serializable objects.
The first tow types's ClassDescriptor should be written, the third one just
write its class name.
Here is the 2.0.0-M5 source code modified:
@Override
public Object getObject(final ClassLoader classLoader)
throws ClassNotFoundException {
if (!prefixedDataAvailable(4)) {
throw new BufferUnderflowException();
}
int length = getInt();
if (length <= 4) {
throw new BufferDataException(
"Object length should be greater than 4: " + length);
}
int oldLimit = limit();
limit(position() + length);
try {
ObjectInputStream in = new ObjectInputStream(asInputStream()) {
@Override
protected ObjectStreamClass readClassDescriptor()
throws IOException, ClassNotFoundException {
int type = read();
if (type < 0) {
throw new EOFException();
}
switch (type) {
case 0: // NON-Serializable class or Primitive types
return super.readClassDescriptor();
case 1: // Serializable class
String className = readUTF();
Class<?> clazz = Class.forName(className, true,
classLoader);
return ObjectStreamClass.lookup(clazz);
default:
throw new StreamCorruptedException(
"Unexpected class descriptor type: " + type);
}
}
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
String name = desc.getName();
try {
return Class.forName(name, false, classLoader);
} catch (ClassNotFoundException ex) {
return super.resolveClass(desc);
}
}
};
return in.readObject();
} catch (IOException e) {
throw new BufferDataException(e);
} finally {
limit(oldLimit);
}
}
@Override
public IoBuffer putObject(Object o) {
int oldPos = position();
skip(4); // Make a room for the length field.
try {
ObjectOutputStream out = new ObjectOutputStream(asOutputStream()) {
@Override
protected void writeClassDescriptor(ObjectStreamClass desc)
throws IOException {
try {
Class<?> clz = Class.forName(desc.getName());
if (!Serializable.class.isAssignableFrom(clz)) { //
NON-Serializable class
write(0);
super.writeClassDescriptor(desc);
} else { // Serializable class
write(1);
writeUTF(desc.getName());
}
}
catch (ClassNotFoundException ex) { // Primitive types
write(0);
super.writeClassDescriptor(desc);
}
}
};
out.writeObject(o);
out.flush();
} catch (IOException e) {
throw new BufferDataException(e);
}
// Fill the length field
int newPos = position();
position(oldPos);
putInt(newPos - oldPos - 4);
position(newPos);
return this;
}
The attachment is a test case.
2009-06-05
Wangzhenghang