{
throw new WicketNotSerializableException(
toPrettyPrintedStack(obj.getClass().getName()), exception);
}
ObjectStreamClass desc;
for (;;)
{
try
{
desc = (ObjectStreamClass)LOOKUP_METHOD.invoke(null, new Object[] { cls,
Boolean.TRUE });
Class repCl;
if (!((Boolean)HAS_WRITE_REPLACE_METHOD_METHOD.invoke(desc, null)).booleanValue() ||
(obj = INVOKE_WRITE_REPLACE_METHOD.invoke(desc, new Object[] { obj })) == null ||
(repCl = obj.getClass()) == cls)
{
break;
}
cls = repCl;
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
throw new RuntimeException(e);
}
}
if (cls.isPrimitive())
{
// skip
}
else if (cls.isArray())
{
checked.put(obj, null);
Class ccl = cls.getComponentType();
if (!(ccl.isPrimitive()))
{
Object[] objs = (Object[])obj;
for (int i = 0; i < objs.length; i++)
{
String arrayPos = "[" + i + "]";
simpleName = arrayPos;
fieldDescription += arrayPos;
check(objs[i]);
}
}
}
else if (obj instanceof Externalizable && (!Proxy.isProxyClass(cls)))
{
Externalizable extObj = (Externalizable)obj;
try
{
extObj.writeExternal(new ObjectOutputAdaptor()
{
private int count = 0;
public void writeObject(Object streamObj) throws IOException
{
// Check for circular reference.
if (checked.containsKey(streamObj))
{
return;
}
checked.put(streamObj, null);
String arrayPos = "[write:" + count++ + "]";
simpleName = arrayPos;
fieldDescription += arrayPos;
check(streamObj);
}
});
}
catch (Exception e)
{
if (e instanceof WicketNotSerializableException)
{
throw (WicketNotSerializableException)e;
}
log.warn("error delegating to Externalizable : " + e.getMessage() + ", path: " +
currentPath());
}
}
else
{
Method writeObjectMethod = null;
Object o = writeObjectMethodCache.get(cls);
if (o != null)
{
if (o instanceof Method)
{
writeObjectMethod = (Method)o;
}
}
else
{
try
{
writeObjectMethod = cls.getDeclaredMethod("writeObject",
new Class[] { java.io.ObjectOutputStream.class });
}
catch (SecurityException e)
{
// we can't access/ set accessible to true
writeObjectMethodCache.put(cls, Boolean.FALSE);
}
catch (NoSuchMethodException e)
{
// cls doesn't have that method
writeObjectMethodCache.put(cls, Boolean.FALSE);
}
}
final Object original = obj;
if (writeObjectMethod != null)
{
class InterceptingObjectOutputStream extends ObjectOutputStream
{
private int counter;
InterceptingObjectOutputStream() throws IOException
{
super(DUMMY_OUTPUT_STREAM);
enableReplaceObject(true);
}
protected Object replaceObject(Object streamObj) throws IOException
{
if (streamObj == original)
{
return streamObj;
}
counter++;
// Check for circular reference.
if (checked.containsKey(streamObj))
{
return null;
}
checked.put(original, null);
String arrayPos = "[write:" + counter + "]";
simpleName = arrayPos;
fieldDescription += arrayPos;
check(streamObj);
return streamObj;
}
}
try
{
InterceptingObjectOutputStream ioos = new InterceptingObjectOutputStream();
ioos.writeObject(obj);
}
catch (Exception e)
{
if (e instanceof WicketNotSerializableException)
{
throw (WicketNotSerializableException)e;
}
log.warn("error delegating to writeObject : " + e.getMessage() + ", path: " +
currentPath());
}
}
else
{
Object[] slots;
try
{
slots = (Object[])GET_CLASS_DATA_LAYOUT_METHOD.invoke(desc, null);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
for (int i = 0; i < slots.length; i++)
{
ObjectStreamClass slotDesc;
try
{
Field descField = slots[i].getClass().getDeclaredField("desc");
descField.setAccessible(true);
slotDesc = (ObjectStreamClass)descField.get(slots[i]);