Найти путь к некорректной непериализуемой переменной-члену

В Java сериализация делает чтение и запись объектов в потоки действительно легкими. Например, следующий фрагмент кода - это почти все, что требуется для записи объектов в поток:

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 ссылка должна бытьSerializable, Предположим, что единственная проблема с этим кодом состоит в том, что что-то внутриtoWrite неSerializable.

Если иерархия не полностьюSerializableПризыв кoos.writeObject(toWrite) бросаетjava.io.NotSerializableException, Это все хорошо, за исключением того, что Исключение не дает вам достаточно всего, чтобы быстро решить проблему. Он скажет вам, какой класс не может быть сериализован. Ваша трассировка стека может выглядеть примерно так:

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 который был установлен на экземплярClassIDidntExplicitlyReference, который неSerializable, Я хотел бы увидеть что-то вроде следующего:

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

Я знаю, что эта проблема, вероятно, не имеет быстрого решения, и, вероятно, будет включать использование отражений. Кто-нибудь здесь на SO делал это раньше, и если да, не могли бы вы поделиться своим пониманием?

Ответ

Я в конечном итоге с помощью отраженияField а такжеModifier класс, чтобы найти путь. К сожалению, я не могу поделиться своим кодом (против политики компании), но я могу показать вам мой вывод. Класс A содержит экземпляр B, B содержит экземпляр C, а C содержит экземпляр D. ВсеSerializable за исключением D. Я использовал Depth-First-Search, чтобы найти путь:

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

Если я сделаюC.d переходный процесс, поиск не дает результатов. Довольно круто!

Ответы на вопрос(3)

Ваш ответ на вопрос