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

В 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Класс S реализует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

Я знаю, что эта проблема, вероятно, неУ него нет быстрого решения, и, скорее всего, оно будет связано с использованием Reflections. Кто-нибудь здесь на 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)

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