跟踪JSF应用程序中的序列化问题

时间:2014-02-12 11:33:48

标签: java serialization jsf-2

我们有一个JSF应用程序,它有时会让我们知道NotSerializableException,而我们不知道哪个对象会出现问题。 Stacktrace几乎没有提供线索,因为它声明“Object”是无法序列化的类型。

我想找到定位该领域的不同方法。

我们已经解决了我发布的解决方案的问题,但我想a)分享它并且b)看看是否可以改进。

1 个答案:

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

}