
|
If you were logged in you would be able to see more operations.
|
|
|
| Resolution Date: |
17/Feb/07 11:33 PM
|
|
The JDK's default serialization exception doesn't give a whole lot of information other than the object that didn't implement serializable. We can try to improve on this by giving more info of the object tree that was being serialized
|
|
Description
|
The JDK's default serialization exception doesn't give a whole lot of information other than the object that didn't implement serializable. We can try to improve on this by giving more info of the object tree that was being serialized |
Show » |
|
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.LinkedList;
public class Foo extends ObjectOutputStream {
private static final long serialVersionUID = 1L;
private LinkedList stack = new LinkedList();
private HashSet set = new HashSet();
public static void main(String[] args) throws Exception
{
new Foo().writeObject(new A());
}
public Foo() throws IOException {}
@Override
protected final void writeObjectOverride(Object obj) throws IOException
{
// Check for circular reference.
if (set.contains(obj))
{
return;
}
if (stack.isEmpty())
{
stack.add("Class " + obj.getClass().getName());
}
set.add(obj);
Field[] fields = obj.getClass().getFields();
for (int i = 0; i < fields.length; i++)
{
StringBuffer buffer = new StringBuffer();
Field f = fields[i];
int m = f.getModifiers();
if (fields[i].getType().isPrimitive() || Modifier.isTransient(m))
{
continue;
}
if (Modifier.isPrivate(m))
{
buffer.append("private ");
}
if (Modifier.isProtected(m))
{
buffer.append("protected ");
}
if (Modifier.isPublic(m))
{
buffer.append("public ");
}
if (Modifier.isAbstract(m))
{
buffer.append("abstract ");
}
if (Modifier.isFinal(m))
{
buffer.append("final ");
}
if (Modifier.isStatic(m))
{
buffer.append("static ");
}
if (Modifier.isVolatile(m))
{
buffer.append("volatile ");
}
buffer.append(f.getType().getName()).append("");
buffer.append(" ").append(f.getName());
stack.add(buffer.toString());
if (Serializable.class.isAssignableFrom(fields[i].getType()))
{
try
{
writeObjectOverride(fields[i].get(obj));
}
catch (IllegalAccessException e)
{
throw new RuntimeException(getPrettyPrintedStack(), e);
}
}
else
{
throw new RuntimeException(getPrettyPrintedStack().toString(), new NotSerializableException(fields[i].getType().getName()));
}
stack.removeLast();
}
if (stack.size() == 1)
{
set.clear();
}
}
private String getPrettyPrintedStack()
{
StringBuffer result = new StringBuffer("Unable to serialise class.\nField hierarchy is:");
StringBuffer spaces = new StringBuffer();
while (!stack.isEmpty()) {
spaces.append(" ");
result.append("\n").append(spaces).append(stack.removeFirst());
}
return result.toString();
}
}
class A implements Serializable
{
private static final long serialVersionUID = 1L;
public B myFieldForB = new B();
public D myFieldForD = new D();
}
class B implements Serializable
{
private static final long serialVersionUID = 1L;
public C myFieldForC = new C();
}
class C
{
private static final long serialVersionUID = 1L;
public int foo = 1;
}
class D implements Serializable
{
public int bar = 2;
}