2014-02-12 35 views
1

我們有一個JSF應用程序,它給了我們NotSerializableException,有時候我們並不知道哪個對象存在問題。 Stacktrace沒有提供線索,因爲它聲明「Object」是無法序列化的類型。追蹤JSF應用程序中的序列化問題

我想找到不同的方法來定位字段。

我們已經解決了我發佈的解決方案的問題,但我想a)分享它,並b)看看是否可以改進。

回答

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) 
    { 
    } 

}