openjdk.ruOpenJDK на русском

JEP 154: Remove Serialization

Удаление сериализации

ОтветственныйAlan Bateman
ТипFeature
ОбластьSE
СтатусClosed / Withdrawn
Компонентcore-libs
Обсуждениеcore dash libs dash dev at openjdk dot java dot net
ТрудоёмкостьM
ДлительностьL
ОдобренBrian Goetz
Создан2012/04/01 20:00
Обновлён2025/06/26 14:53
Задача8046144

Аннотация

Объявить устаревшим, отключить и в итоге удалить механизм сериализации платформы Java SE.

Что не является целью

Это предложение не ставит целью ввести альтернативный механизм сериализации.

Мотивация

Разработчики хорошо знают о многочисленных недостатках механизма сериализации Java. О плане удалить его и связанные с ним API в пакете java.io впервые объявили много лет назад.

Одна из причин этого изменения в том, что протокол Object Serialization Stream Protocol серьёзно ограничивает производительность. Протокол проектировался в расчёте на то, что сериализованный поток будет передаваться по ненадёжному соединению. Именно поэтому каждый объект и дескриптор записывается в поток дважды, чтобы получатель мог сравнить байты. В сильно деградированных средах, например на машинах с Microsoft Windows, где работает антивирус McAfee, константа TC_OBJECT и связанные с ней данные объекта могут записываться в сериализованный поток до восьми раз из-за тайм-аутов, вызванных антивирусной проверкой в реальном времени. Было предпринято несколько попыток избежать записи дублирующихся данных в поток, но ни одна не увенчалась успехом из-за проблем с совместимостью.

Менее известная проблема, и главная причина, по которой это изменение отмечалось уже в нескольких выпусках, состоит в том, что доступные значения для serialVersionUID заканчиваются. Хотя serialVersionUID объявлен как long (и, следовательно, доступно до 2^64 значений), в дескрипторе класса (TC_CLASSDESC) он усекается до 32-битного значения. В ранних версиях JDK инструмент serialver обращался к java.sun.com, чтобы по мере необходимости резервировать значения serialVersionUID, и это гарантировало, что значений хватит многим поколениям будущих разработчиков. Этот процесс выделения был прекращён в JDK 6 от Sun и во всех выпусках OpenJDK из-за опасений различных сторонников свободного ПО и защитников конфиденциальности. Его заменили механизмом резервирования, который выделяет большой блок значений serialVersionUID для каждой установки JDK. В результате доступный диапазон значений serialVersionUID быстро истощается, и, по текущим прогнозам, значения, скорее всего, переполнятся и начнутся заново к концу 2012 года. Ожидается, что, как только это произойдёт, многие приложения начнут периодически давать сбой, выбрасывая InvalidObjectException.

Ещё одна причина удалить сериализацию в том, что ключевое слово transient планируется передать другой возможности языка Java, запланированной на один из будущих выпусков. Подробности об этой возможности языка будут изложены в будущем JEP.

Описание

Удаление сериализации Java, очевидно, в некоторой степени повлияет на совместимость, и разработчикам потребуется время, чтобы изменить свои приложения.

Предлагается удалять сериализацию поэтапно, как описано ниже.

В одном из обновлений JDK 7, возможно в update 6, Serializable, ObjectInputStream, ObjectOutputStream и связанные с ними классы в пакете java.io будут объявлены устаревшими. Для этого потребуется соответствующий Maintenance Review спецификации платформы Java SE 7 (JSR 336).

В Java SE 8 эти типы будут удалены, а все классы платформы будут изменены так, чтобы они больше не реализовывали Serializable. Будет введена новая опция VM, возможно -XX:+EnableSerialization, как опция совместимости, чтобы снова включать сериализацию для приложений, которым она ещё нужна. Как именно будет работать эта опция, требует дальнейшего изучения. Один из подходов — собирать две копии rt.jar: одну с классами, реализующими Serializable, и другую (по умолчанию) с классами, которые не реализуют Serializable. Поскольку JDK 8 планируется поставлять в модульном виде, возможно, удастся поставлять по две копии каждого модуля JDK. Будут также изучены другие подходы, в том числе методы инструментирования байт-кода.

В Java SE 9 опция включения сериализации будет удалена.

Риски и допущения

Реализация этого предложения может затруднить переход на Java 8.

Есть некоторая вероятность, что экспертная группа Java SE 8 (JSR 337) возразит против этого плана или, как минимум, существенно его переработает.

Если для опции совместимости, снова включающей сериализацию, потребуется поставлять JDK с двумя копиями rt.jar (или двумя копиями модулей JDK), это может несколько увеличить размер загружаемого JDK.

Влияние

  • Совместимость: высокое
  • Документация: среднее
  • TCK: высокое
  • Twitter: высокое