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

JEP 322: Time-Based Release Versioning

Версионирование выпусков по времени

ОтветственныйMark Reinhold
ТипFeature
ОбластьSE
СтатусClosed / Delivered
Выпуск10
Компонентcore-libs / java.lang
Обсуждениеjdk dash dev at openjdk dot java dot net
ТрудоёмкостьM
ДлительностьS
РецензентыAlan Bateman, Alex Buckley, Dalibor Topic, Iris Clark, John Rose
ОдобренBrian Goetz
Создан2017/11/30 17:51
Обновлён2026/08/04 19:07
Задача8192828

Аннотация

Пересмотреть схему строк версий платформы Java и JDK, а также связанную информацию о версиях, для нынешней и будущих моделей выпусков по времени.

Цели

  • Переработать схему номеров версий, введённую в JEP 223, чтобы она лучше подходила для моделей выпусков по времени, в которых определены выпуски Feature Release (функциональный выпуск), которые могут содержать новые возможности, и выпуски обновлений, которые только исправляют ошибки.

  • Допустить модели выпусков по времени, отличные от текущей модели: с другой периодичностью или с промежуточными выпусками, которые меньше выпусков Feature Release, но больше выпусков обновлений.

  • Сохранить совместимость с общей схемой строк версий из JEP 223.

  • Дать разработчику или конечному пользователю простой способ понять, насколько стар выпуск, чтобы он мог решить, стоит ли обновить его до более нового выпуска с последними исправлениями безопасности и, возможно, дополнительными возможностями.

  • Дать поставщику реализации способ указать, что выпуск входит в серию выпусков, для которых этот поставщик предоставляет Long-Term Support (долгосрочная поддержка).

  • Дать поставщику реализации способ включать и отображать дополнительную строку версии, специфичную для поставщика, чтобы согласовать выпуск со связанными продуктами.

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

Целью не является пересмотр существующей схемы строк версий для удовлетворения требований, не связанных с моделями выпусков по времени.

Целью не является пересмотр вывода сведений о версии у инструментов командной строки, кроме средства запуска java. Это желательно, но не критично, и может быть сделано позже.

Мотивация

Схема строк версий, введённая в JEP 223, была значительным улучшением по сравнению с прежней. Однако эта схема плохо подходит для будущего, в котором мы намерены выпускать новые версии платформы Java и JDK строго раз в шесть месяцев.

Главная трудность схемы JEP 223 в том, что номер версии выпуска кодирует его значимость и совместимость по отношению к предшественникам. Однако в модели выпусков по времени эти качества заранее неизвестны. Они могут меняться на протяжении всего цикла разработки выпуска, пока не будет интегрирована последняя возможность. Поэтому номер версии выпуска тоже заранее неизвестен.

При семантике номеров версий из JEP 223 каждому, кто работает над выпуском JDK или создаёт либо использует компоненты поверх него, придётся сначала говорить о дате выпуска, а затем, когда номер версии станет известен, переходить на него. Разработчикам, сопровождающим библиотеки, фреймворки и инструменты, придётся быть готовыми менять код, проверяющий номера версий, в конце каждого без исключения цикла выпуска JDK. Это неудобно и сбивает с толку всех участников.

Поэтому главное предлагаемое здесь изменение — переработать номера версий так, чтобы они кодировали не совместимость и значимость, а ход времени, измеряемый циклами выпусков. Это лучше подходит для моделей выпусков по времени, поскольку каждый цикл выпуска, а значит и номер версии каждого выпуска, всегда известен задолго заранее.

Описание

Номера версий

Номер версии, $VNUM, — это непустая последовательность элементов, разделённых символами точки (U+002E). Элемент — это либо ноль, либо беззнаковое целое число без ведущих нулей. Последний элемент номера версии не должен быть нулём. При увеличении элемента все последующие элементы удаляются. Формат:

[1-9][0-9]*((\.0)*\.[1-9][0-9]*)*

Последовательность может иметь произвольную длину, но первым четырём элементам присвоены определённые значения:

$FEATURE.$INTERIM.$UPDATE.$PATCH
  • $FEATURE — счётчик выпусков Feature Release, увеличивается с каждым выпуском Feature Release независимо от его содержания. В выпуске Feature Release возможности могут добавляться; они также могут удаляться, если об этом было заранее объявлено как минимум за один выпуск Feature Release. Несовместимые изменения могут вноситься, если они обоснованы. (Ранее $MAJOR.)

  • $INTERIM — счётчик промежуточных выпусков, увеличивается для выпусков, не являющихся Feature Release, которые содержат совместимые исправления ошибок и улучшения, но не содержат несовместимых изменений, удалений возможностей и изменений стандартных API. (Ранее $MINOR.)

  • $UPDATE — счётчик выпусков обновлений, увеличивается для совместимых выпусков обновлений, которые исправляют проблемы безопасности, регрессии и ошибки в более новых возможностях. (Ранее $SECURITY, но с нетривиальным правилом увеличения.)

  • $PATCH — счётчик выпусков-патчей, увеличивается для совместимых выпусков-патчей, которые исправляют небольшое число критических проблем. (Использование для этого дополнительного элемента сводит к минимуму неудобства как для разработчиков, так и для пользователей выпусков обновлений, находящихся в работе.)

Пятый и последующие элементы номеров версий зарезервированы для использования последующими потребителями кодовой базы JDK. Пятый элемент может использоваться, например, для обозначения выпусков-патчей конкретного поставщика реализации.

Номер версии никогда не содержит завершающих нулевых элементов. Если элемент и все следующие за ним логически равны нулю, все они опускаются.

Последовательность чисел в номере версии сравнивается с другой такой последовательностью поэлементно, в числовом порядке; например, 10.0.4 меньше, чем 10.1.2. Если одна последовательность короче другой, недостающие элементы более короткой последовательности считаются меньше соответствующих элементов более длинной; например, 10.0.2 меньше, чем 10.0.2.1.

Номера версий в шестимесячной модели выпусков

В шестимесячной модели выпусков элементы номеров версий меняются следующим образом:

  • $FEATURE увеличивается каждые шесть месяцев: выпуск марта 2018 года — JDK 10, выпуск сентября 2018 года — JDK 11 и так далее.

  • $INTERIM всегда равен нулю, поскольку шестимесячная модель не включает промежуточных выпусков. Мы резервируем его здесь ради гибкости, чтобы будущая редакция модели выпусков могла включить такие выпуски и объявить JDK $N.1 и JDK $N.2 совместимыми обновлениями JDK $N. Например, выпуски JDK 1.4.1 и 1.4.2 по сути были промежуточными и по этой схеме получили бы номера 4.1 и 4.2.

  • $UPDATE увеличивается через месяц после увеличения $FEATURE и затем каждые три месяца: выпуск апреля 2018 года — JDK 10.0.1, июльский выпуск — JDK 10.0.2 и так далее.

Мы действительно ожидаем, что большинство выпусков Feature Release будут содержать хотя бы одну-две значимые возможности, а выпуски обновлений никогда не будут включать несовместимых изменений. С учётом того, что $INTERIM всегда равен нулю, на практике эта схема часто будет давать номера версий, мало отличающиеся от тех, что дала бы схема JEP 223.

Строки версий

Общий формат строк версий такой же, как определённый в JEP 223. Строка версии — это номер версии, $VNUM, за которым могут следовать сведения о предварительном выпуске, сборке и другие необязательные сведения, в одном из вариантов:

$VNUM(-$PRE)?\+$BUILD(-$OPT)?
$VNUM-$PRE(-$OPT)?
$VNUM(+-$OPT)?

где $PRE — идентификатор предварительного выпуска (например, ea), $BUILD — номер сборки, а $OPT — необязательные сведения о сборке.

Если выпуск входит в серию выпусков, для которых поставщик реализации предоставляет Long-Term Support, значение $OPT должно начинаться с "LTS", например 11.0.2+13-LTS. Тогда "LTS" будет заметно отображаться в выводе java --version и т. д.; подробнее об этом ниже.

API

Мы пересматриваем API Runtime.Version, определённый в JEP 223, следующим образом:

  • Добавить четыре новых метода доступа, возвращающих int, для основных компонентов номеров версий, определённых выше: feature(), interim(), update() и patch().

  • Переопределить существующие методы доступа major(), minor() и security() так, чтобы они возвращали те же значения, что и feature(), interim() и update() соответственно.

  • Пометить существующие методы доступа как Deprecated (устаревший), но не для удаления, с рекомендацией использовать соответствующие новые методы. Это поможет разработчикам понять новую семантику номеров версий.

Системные свойства

К системным свойствам, упомянутым в JEP 223, мы добавляем два новых свойства:

  • java.version.date — дата выпуска этой версии в статусе General Availability (общедоступный выпуск), GA, в формате ISO-8601 YYYY-MM-DD. Для выпусков Early Access (ранний доступ) это будет планируемая дата GA, т. е. некоторая дата в будущем.

Это новое свойство позволяет легко понять, насколько стар выпуск, чтобы вы как пользователь могли оценить, насколько отстаёте. Оно также отражает уровень безопасности выпуска: конкретный выпуск GA содержит последние исправления безопасности, если его дата версии не раньше даты любого другого выпуска GA.

  • java.vendor.version — строка версии продукта, специфичная для поставщика реализации; её может задать человек или организация, выпускающие конкретную реализацию. Если она не задана при сборке, у свойства нет значения; иначе его значение — непустая строка, соответствующая регулярному выражению \p{Graph}+.

Это новое свойство позволяет поставщикам реализаций указывать дополнительные сведения о версии, которые могут понадобиться для согласования со связанными продуктами. Поставщик, в линейке продуктов которого используются, например, версии на основе дат вида $YEAR.$MONTH, может задать это свойство соответствующим образом, чтобы его выпуски JDK были явно связаны с другими его выпусками. (Это свойство называется java.vendor.version, а не более очевидным java.implementor.version, чтобы соответствовать существующим системным свойствам, в именах которых есть vendor.)

Средство запуска

Средство запуска java будет отображать строки версий и системные свойства следующим образом (для гипотетической сборки 13 JDK 10.0.1):

$ java --version
openjdk 10.0.1 2018-04-19
OpenJDK Runtime Environment (build 10.0.1+13)
OpenJDK 64-Bit Server VM (build 10.0.1+13, mixed mode)
$

Аналогично для гипотетической сборки 42 JDK 11, выпуска LTS:

$ java --version
openjdk 11 2018-09-20 LTS
OpenJDK Runtime Environment (build 11+42-LTS)
OpenJDK 64-Bit Server VM (build 11+42-LTS, mixed mode)
$

Если поставщик реализации назначит сборке JDK 11 LTS строку версии поставщика, например, 18.9, она будет отображаться так:

$ java --version
openjdk 11 2018-09-20 LTS
OpenJDK Runtime Environment 18.9 (build 11+42-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11+42-LTS, mixed mode)
$

Подробнее: вывод параметров средства запуска java, сообщающих версию, будет оформлен следующим образом, где ${LTS} раскрывается в "\u0020LTS", если первые три символа $OPT — это "LTS", а ${JVV} раскрывается в "\u0020${java.vendor.version}", если это системное свойство определено:

$ java --version
openjdk ${java.version} ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
$ 

$ java --show-version < ... >
openjdk ${java.version} ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
[ ... ]
$ 

$ java --full-version
openjdk ${java.runtime.version}
$ 

$ java -version
openjdk version \"${java.version}\" ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
$ 

$ java -showversion < ... >
openjdk version \"${java.version}\" ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
[ ... ]
$ 

$ java -fullversion
openjdk full version \"${java.runtime.version}\"
$

Тег JavaDoc @since

Значение, используемое с тегом JavaDoc @since, по-прежнему согласовано с системным свойством java.specification.version, поэтому API, появившиеся в JDK 10, будут помечены @since 10.

Теги наборов изменений Mercurial

Общий синтаксис тегов Mercurial, обозначающих опубликованные (promoted) сборки, не меняется: jdk\-$VNUM\+$BUILD.

Конфигурация сборки и её результаты

Три существующих параметра конфигурации, связанных с версией, будут помечены как Deprecated и потому будут игнорироваться, а соответствующие переменные Make больше не будут определяться:

--with-version-major          VERSION_MAJOR
--with-version-minor          VERSION_MINOR
--with-version-security       VERSION_SECURITY

Будут определены пять новых параметров и соответствующие переменные:

--with-version-feature        VERSION_FEATURE
--with-version-interim        VERSION_INTERIM
--with-version-update         VERSION_UPDATE
--with-version-date           VERSION_DATE
--with-vendor-version-string  VENDOR_VERSION_STRING

(Определять --with-version-patch и VERSION_PATCH не нужно, поскольку они уже существуют.)

Файл release, записываемый в корень образа JDK, помимо существующей переменной JAVA_VERSION будет также определять JAVA_VERSION_DATE со значением системного свойства java.version.date и IMPLEMENTOR_VERSION со значением системного свойства java.vendor.version, если оно определено.

Альтернативы

В предложении о шестимесячной модели выпусков по времени предлагалось, чтобы строки версий выпусков Feature Release имели вид $YEAR.$MONTH. Тогда мартовский выпуск следующего года был бы 18.3, сентябрьский — 18.9, и так каждый год.

После того как против этой схемы были выдвинуты обоснованные возражения, мы рассмотрели различные виды информации, кодируемой в номерах версий, и предложили несколько альтернатив, затем подвели итоги последовавшего обсуждения и ответили на него и, наконец, опубликовали предложение, которое было хорошо принято и поэтому стало основой этого JEP.

Тестирование

Эта новая схема строк версий в основном совместима со схемой, определённой в JEP 223, поэтому тестирование должно быть несложным. Главное отличие — возможное использование четвёртого элемента для выпусков-патчей, что может потребовать новых модульных тестов. Изменения соответствующих параметров конфигурации сборки потребуют несложного ручного тестирования.

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

Описанные здесь изменения вносят три незначительные несовместимости:

  • JEP 223 определяет, что метод security() из API Runtime.Version возвращает значение элемента $SECURITY номера версии. Этот элемент не увеличивается, когда увеличивается предшествующий ему элемент $MINOR. Это предложение переименовывает элемент $SECURITY в $UPDATE и сбрасывает этот элемент при каждом увеличении предшествующего ему элемента $INTERIM (ранее $MINOR). Поэтому переопределение security() через update() теоретически является несовместимым изменением. Однако этот API появился в JDK 9, и выпуски JDK 9 с ненулевым значением $MINOR не предполагаются, так что на практике это изменение должно иметь минимальные последствия.

  • Вывод параметров лаунчера java, сообщающих версию, теперь включает дату версии в конце первой строки, после которой может следовать "\u0020LTS". Существующий код, который разбирает этот вывод в предположении, что последний токен в строке — номер версии, может потребовать доработки.

  • Вывод параметров --version, --show-version, -version и -showversion лаунчера java будет включать значение системного свойства java.vendor.version во второй и третьей строках, если это значение отличается от значения java.version. Существующий код, который разбирает этот вывод, может потребовать доработки.