Java.io.WriteAbortedException: запись прерывается; java.io.NotSerializableException

Что вызывает такую ​​ошибку в Tomcat?

SEVERE: Exception loading sessions from persistent storage
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException:
   bean.ProjectAreaBean
 at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1333)
 at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
 at java.util.ArrayList.readObject(ArrayList.java:593)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(
    DelegatingMethodAccessorImpl.java:25)

Ответ 1

Просто реализуйте Serializable

Если вы получаете NotSerializableException как NotSerializableException ниже,

java.io.NotSerializableException: bean.ProjectAreaBean

тогда это просто означает, что класс, идентифицируемый полностью определенным именем в сообщении об исключении (которое в вашем случае является bean.ProjectAreaBean), не реализует интерфейс Serializable то время как это ожидается кодом, стоящим за ним. Исправить это относительно просто, просто позвольте классу реализовать интерфейс Serializable.

package bean;

import java.io.Serializable;

public class ProjectAreaBean implements Serializable {
    private static final long serialVersionUID = 1L;

    // ...
}

Поле serialVersionUID не является обязательным, но настоятельно рекомендуется, поскольку оно поддерживает двоичную совместимость между различными версиями класса и сериализованными представлениями его экземпляров. Поэтому, когда вы позже добавите новое сериализуемое поле в класс, вам нужно будет изменить поле serialVersionUID (обычно достаточно просто увеличить его на 1), чтобы предотвратить проблемы при десериализации экземпляра более старой версии класса. Среды IDE, такие как Eclipse, также предлагают возможность (пере) генерировать значение serialVersionUID которое в основном является хешем, вычисляемым на основе всех полей.

Смотрите также:


Пометить несериализуемые поля как transient

Если ваш класс Serializable содержит, в свою очередь, поле/свойство, ссылающееся на экземпляр другого класса, который абсолютно нельзя сделать Serializable (обычно это представляют ресурсы, такие как InputStream, Connection и т.д.), Вам необходимо пометить его как transient. Таким образом, он будет пропущен во время сериализации класса.

private transient SomeObject thisWillNotBeSerialized;

Вы должны понимать, что после десериализации это поле всегда будет null. Обратите внимание, что конструктор класса и блоки инициализации не вызываются во время десериализации. Если вы хотите иметь более точный контроль над сериализацией и десериализацией, переопределите readObject() и writeObject(). Вы можете найти конкретные примеры в ссылках ниже:


Почему сериализация?

Что касается того, почему вам нужно беспокоиться о сериализации, то это потому, что большинству контейнеров сервлетов Java, таких как Tomcat, требуются классы для реализации Serializable всякий раз, когда экземпляры этих классов хранятся в качестве атрибута HttpSession. Это связано с тем, что HttpSession возможно, необходимо сохранить в локальной файловой системе на диске или даже передать по сети, когда сервлет-контейнер необходимо отключить/перезапустить или он помещается в кластер серверов, где сеанс должен быть синхронизирован.

Чтобы иметь возможность сохранять объекты Java в файловой системе локального диска или передавать их по сети, их необходимо сначала преобразовать в поток байтов (в основном: byte[] или InputStream), и это возможно только в том случае, если класс за объектом реализует Serializable. Сам интерфейс Serializable ничего не делает, это просто маркерный интерфейс. Код только делает instanceof Serializable проверки атрибута сеанса, чтобы действовать соответственно.

Смотрите также:

Ответ 2

Вам нужно сделать bean.ProjectAreaBean сериализуемым.