我们有一个JSF应用程序,它有时会让我们知道NotSerializableException,而我们不知道哪个对象会出现问题。 Stacktrace几乎没有提供线索,因为它声明“Object”是无法序列化的类型。
我想找到定位该领域的不同方法。
我们已经解决了我发布的解决方案的问题,但我想a)分享它并且b)看看是否可以改进。
答案 0 :(得分:1)
我们创建了以下类并将其添加为web.xml的侦听器。这会导致性能下降,因此如果性能问题,请不要忘记再次将其删除。除了在集群上序列化servlet之外,这引发了大部分序列化问题。
public class SessionAttributeTracker implements HttpSessionAttributeListener
{
private static final Logger logger = LoggerFactory.getLogger(SessionAttributeTracker.class);
@Override
public void attributeAdded(final HttpSessionBindingEvent sessionBindingEvent)
{
Object obj = sessionBindingEvent.getValue();
logger.debug("Session attribute added: {}", obj);
if (!isSerializable(obj))
{
logger.warn("Attribute '{}' added to session with non-serializable object: {}",
sessionBindingEvent.getName(),
sessionBindingEvent.getValue());
}
}
private boolean isSerializable(final Object obj)
{
logger.debug("Checking serializability of : {}", obj.getClass().getName());
boolean ret = false;
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try
{
oos = new ObjectOutputStream(out);
oos.writeObject(obj);
ret = true;
}
catch (Exception e)
{
for (Field f : obj.getClass().getDeclaredFields())
{
logger.trace("obj {} felt {}", obj, f.getName());
if ((f.getModifiers() & Modifier.TRANSIENT) == 0)
{
f.setAccessible(true);
try
{
Object object = f.get(obj);
oos = new ObjectOutputStream(out);
// logger.debug("Hopper over writeObject");
oos.writeObject(object);
}
catch (Exception e1)
{
logger.debug("Problem encountered while serializing attribute {}", f.getName(), e1);
}
}
}
logger.warn("Serilization problem.", e);
return ret;
}
finally
{
IOUtils.closeQuietly(oos);
}
return ret;
}
private String threadDump()
{
StringBuffer fullThreadDump = new StringBuffer();
Thread t = Thread.currentThread();
State state = t.getState();
String tName = t.getName();
if (state != null)
{
fullThreadDump.append(" ").append(tName).append(": ").append(state).append("\n");
}
StackTraceElement[] stes = t.getStackTrace();
for (StackTraceElement stackTraceElement : stes)
{
fullThreadDump.append(" at ").append(stackTraceElement).append("\n");
}
return fullThreadDump.toString();
}
@Override
public void attributeRemoved(final HttpSessionBindingEvent sessionBindingEvent)
{
}
@Override
public void attributeReplaced(final HttpSessionBindingEvent sessionBindingEvent)
{
}
}