在运行时修改Java类以使实例字段瞬态 - 它会起作用吗?

时间:2010-01-15 23:13:34

标签: java session weblogic

当我们使HTTPSession具有无法序列化的对象(我们不关心但会污染我们的日志)时,我们会发出一条来自Weblogic的烦人日志消息。调整我们的log4j配置以不记录此消息似乎不是一个选项(消息来自通用的Weblogic类,我们不想压缩来自这个类的所有消息,除了编写我们自己的适配器来查看消息写入日志并抑制反序列化错误消息我不知道如何通过log4j配置来实现它。

为了暂时修复此问题以清理我们的日志,我想拦截调用以将对象添加到HTTP会话,以便添加的对象的类(以及其对象图中的任何对象)的实例变量声明已更改暂时的。我想通过添加一个HTTPSesssionEventListener来拦截调用,然后使用反射库修改Class的实例变量。

有谁知道这是否有效?

4 个答案:

答案 0 :(得分:2)

  

有没有人有更好的建议和/或知道这会不会像我希望的那样起作用?

是。 构建规范!

符合Java Servlet规范:

  

分布式servlet容器必须抛出IllegalArgumentException   对于容器不能支持所需机制的对象   迁移存储它们的会话。

因此,如果您想避免此消息(并编写好的可移植和可分发代码),只需使您放在HttpSession中的对象实现Serializable接口即可。

说真的,我无法相信你正在考虑解决方法来解决真正的问题,而不是修复它。

答案 1 :(得分:1)

一个选项,如果

tail -f yourlog | grep -v "annoying line here" > cleanLogFile

这更不容易打扰。但是会创建第二个文件。

我为一个项目做了这个,我需要跟踪一个特定的问题和所有那些愚蠢的消息,其中介于中间。

答案 2 :(得分:0)

尝试修改ObjectOutputStream,而不是序列化对象。

如果扩展ObjectOutputStream,则可以覆盖replaceObject方法并清除不可序列化的字段或重新创建没有非可序列化属性的对象。

另一种选择是使用反射来使会话对象的非可序列化字段无效,但这是非常危险的,因为会话对象可以加载回来并且似乎可以工作但是然后抛出NullPointerException小时甚至是几个月后(最终引用你无效的字段。)

修改类可能不起作用。

可以在实例字段上扩展ClassLoader和调整标志,但是:

  • 如果您的类包含非可序列化字段,那么自行更改代码以使其成为瞬态更简单
  • 如果它不是你的类,那么它将被你的应用程序类中的不同ClassLoader加载,所以当你看到该对象时它将为时已晚(因为该类已被加载。)

您不能在单个对象上设置transient标志,只能在类上设置。

答案 3 :(得分:0)

为什么要去那个麻烦?只要有问题的所有对象都是你的,就可以很容易地将它们全部标记为Serializable。

如果那是不可能的,.a另一种方法是在webApp中注册一个实现HttpSessionAttributeListener的类。在attributeAdded方法中,打印sessionID,然后序列化会话数据:

public void attributeAdded(HttpSessionBindingEvent hsbe)
{
    // Handle the details yourself here.
    ObjectOutputStream.writeObject(hsbe.getValue())
}