查找违反非Serializable成员变量的路径 [英] Find path to offending non-Serializable member variable

查看:105
本文介绍了查找违反非Serializable成员变量的路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,Serialization使得对象的读取和写入非常容易。例如,以下代码片段主要用于将对象写入流:

In Java, Serialization makes reading and writing objects to streams REALLY easy. For instance, the following code snippet is mostly all it takes to write objects to a stream:

ObjectOutputStream oos = ... //Initialize your output stream
Object toWrite = ...         //Initialize what you want to write here
oos.writeObject(toWrite);    //Writes the object to the stream
oos.flush();

如果 toWrite 的类实现 Serializable 接口,并且所有 toWrite 的非 transient 成员变量也是 Serializable 。换句话说,您尝试通过 toWrite 引用发送的整个Object层次结构必须是 Serializable 。假设此代码的唯一问题是 toWrite 内的某些内容不是 Serializable

This will work just fine, provided that toWrite's class implements the Serializable interface, AND that all of toWrite's non-transient member variables are also Serializable. In other words, the entire Object hierarchy you are trying to send via the toWrite reference must be Serializable. Assume that the only problem with this code is that something inside toWrite isn't Serializable.

如果层次结构不完全 Serializable ,则调用 oos.writeObject(toWrite)抛出 java.io.NotSerializableException 。这一切都很好,除了Exception不能为您提供快速解决问题所需的一切。它会告诉你哪些类无法序列化。您的堆栈跟踪可能如下所示:

If the hierarchy isn't completely Serializable, the call to oos.writeObject(toWrite) throws a java.io.NotSerializableException. This is all fine and good, except that the Exception doesn't give you quite everything you need to fix the problem quickly. It will tell you what class couldn't be serialized. Your stack trace might look something like this:

java.io.NotSerializableException: some.package.and.ClassIDidntExplicitlyReference
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    ...
    at my.package.MyClass.codeThatWroteTheOffendingObject(MyClass.java:###)

这种方式指向正确的方向,但涉及 toWrite ,并不总是清楚违规类引用的来源。假设我将 toWrite 分配给 MyClass 的实例以及我的 MyClass 有一个名为 nonSerializableReference 的成员Object引用,它已被设置为 ClassIDidntExplicitlyReference 的实例,这不是序列化。我希望看到以下内容打印出来:

This sort of points you in the right direction, but in cases that involve deep Object hierarchies referenced by toWrite, it's not always clear where the offending class reference came from. Let's say I assign toWrite to an instance of MyClass and my instance of MyClass has a member Object reference called nonSerializableReference that has been set to an instance of ClassIDidntExplicitlyReference, which is not Serializable. I'd like to see something like the following printed out:

my.package.MyClass.nonSerializableReference instanceof some.package.and.ClassIDidntExplicitlyReference

我知道这个问题可能没有快速解决方案,可能会涉及使用Reflections 。有没有人在这里做过这件事,如果有的话,你介意分享你的见解吗?

I know this problem probably doesn't have a quick solution, and will likely involve using Reflections. Has anyone here on SO done this before and if so, would you mind sharing your insight?

回答

我最终使用Reflection的 Field Modifier 类来查找路径。不幸的是,我不能分享我的代码(违反公司政策),但我可以告诉你我的输出。 A类持有B的实例,B持有C的实例,C持有D的实例。除了D之外,所有都是 Serializable 我最终使用了Depth-First - 搜索以找到路径:

I ended up using Reflection's Field and Modifier class to find the path. Unfortunately, I can't share my code (against company policy), but I can show you my output. Class A holds an instance of B, B holds an instance of C, and C holds an instance of D. All are Serializable except for D. I ended up using Depth-First-Search to find the path:

A.b -> 
  B.c -> 
    C.d instanceof class D

如果我赚 Cd transient,搜索没有结果。非常酷!

If I make C.d transient, the search yields no results. Pretty cool!

推荐答案

这是一个奇怪的问题 - 您希望在运行时确定在编译时应该做什么。理论上,对象的路径不应该重要 - 您需要找到引用不可序列化的东西来修复代码的对象。

This is a strange question - you're wanting to determine at runtime what you should be doing at compile time. In theory, the path to the object shouldn't matter - you need to find the objects that reference things that aren't serializable to fix your code.

也就是说,您可以使用反射编写一个简单的递归树爬虫。也就是说,您可以通过实现自己的ObjectInputStream来实现,该ObjectInputStream可以正确记录对象。我建议您查看来源了解更多详情

That said, you could write a simple recursive tree crawler using reflection. That said, you might be able to get away with implementing your own ObjectInputStream that logs the objects coming in appropriately. I recommend taking a look at the source for more detail

这篇关于查找违反非Serializable成员变量的路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆