1
我們有一個JSF應用程序,它給了我們NotSerializableException,有時候我們並不知道哪個對象存在問題。 Stacktrace沒有提供線索,因爲它聲明「Object」是無法序列化的類型。追蹤JSF應用程序中的序列化問題
我想找到不同的方法來定位字段。
我們已經解決了我發佈的解決方案的問題,但我想a)分享它,並b)看看是否可以改進。
我們有一個JSF應用程序,它給了我們NotSerializableException,有時候我們並不知道哪個對象存在問題。 Stacktrace沒有提供線索,因爲它聲明「Object」是無法序列化的類型。追蹤JSF應用程序中的序列化問題
我想找到不同的方法來定位字段。
我們已經解決了我發佈的解決方案的問題,但我想a)分享它,並b)看看是否可以改進。
我們創建了以下類並將其作爲偵聽器添加到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)
{
}
}