Можно ли доверить ИИ миграцию Spring Boot 2.7 → 3.5?

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

В проде у многих команд до сих пор крутится Spring Boot 2.7. Исправления, в том числе по безопасности, для этой версии закончились ещё в ноябре 2023 года, когда вышел 2.7.18, последний открытый релиз всей ветки 2.x. Но миграцию многие команды всё откладывают и откладывают. И нет, причина вовсе не в лени. Просто все понимают, что переход на третью версию затрагивает не только смену номера в build.gradle.

Причём ошибки компиляции тут пугают меньше всего. Замену javax.* на jakarta.* или пропавший WebSecurityConfigurerAdapter видно сразу, потому что проект тупо не собирается. Гораздо неприятнее то, что ломается втихую. Код собрался, сервис поднялся, health-check зелёный, а клиенты вдруг начинают получать 404, 401 и 500 там, где всё работало.

Казалось бы, это идеальная задача для ИИ-агента. Работа большая, нудная и хорошо описана в документации. Но на практике мало кто готов отдать агенту миграцию сервиса, который крутится в проде. И я эти опасения понимаю. Агент вполне может добиться зелёной сборки, поправить пару тестов под новое поведение и бодро отчитаться, что всё готово. А изменения, о которых я написал выше, как раз из тех, что легко пропустить и человеку, и модели.

Поэтому я решил проверить это на деле. Я взял небольшой, но вполне жизненный сервис на Spring Boot 2.7 и попросил Kodacode перевести его на 3.5. Принимать работу на глаз не хотелось, поэтому критерием приёмки стал набор контрактных тестов, который агенту трогать запрещено. Если агенту можно доверять, он пройдёт эти тесты, не меняя в них ни строчки.

Вот о чём пойдёт речь.

  • как устроен подопытный сервис и почему главный риск в его клиентах;

  • как сделать тесты, которые не мигрируют вместе с кодом;

  • что меняется между 2.7 и 3.x и чего из этого не видит компилятор;

  • как агент провёл миграцию и как сам доказал, что каждое его исправление нужно;

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

  • чеклист для вашего сервиса.

Подопытный сервис

Billing Service выставляет и принимает оплату счетов. Он умеет выставлять счёт, показывать список счетов и отдельный счёт, отменять оплату и отдавать плательщику публичную страницу по ссылке из письма.

Метод

Путь

Доступ

Назначение

POST

/api/invoices

Basic

Выставить счёт

GET

/api/invoices

Basic

Список счетов

GET

/api/invoices/{id}

Basic

Счёт по id

POST

/api/invoices/{id}/payments

Basic

Отметить оплату

GET

/api/public/pay/{token}

публичный

Страница оплаты для плательщика

GET

/actuator/health

публичный

Health check

Стек такой, какой обычно бывает у сервиса, написанного несколько лет назад. Java 11, Spring Boot 2.7.18, Spring Data JPA с Hibernate 5.6, Flyway и PostgreSQL. Секурити через WebSecurityConfigurerAdapter и HTTP Basic, трассировка через Spring Cloud Sleuth.

build.gradle.kts: Spring Boot 2.7.18 и Java 11
build.gradle.kts: Spring Boot 2.7.18 и Java 11
Зависимости сервиса: JPA, Security, Sleuth, Flyway
Зависимости сервиса: JPA, Security, Sleuth, Flyway

Но код тут не самое интересное. Интереснее клиенты, потому что сломать миграция может именно их.

  • мобильное приложение 3.x запрашивает списки со слэшем на конце, то есть /api/invoices/;

  • API gateway передаёт контекст трассировки в заголовках B3 и подписанный контекст клиента в X-Client-Context размером до 16 КБ;

  • плательщики открывают /api/public/pay/{token} из письма без авторизации, и если ссылка просрочена, они должны увидеть 404, а не форму входа.

В типичных чеклистах миграции про такое не пишут, а в живых сервисах это встречается сплошь и рядом. Код демо лежит в github.com/befayer/spring-boot-27-migration-demo.

Контрактные тесты вместо доверия на слово

Перед миграцией первым делом хочется опереться на тесты, которые уже есть. Проблема в том, что unit- и интеграционные тесты мигрируют вместе с кодом. В них тоже придётся менять javax на jakarta, чинить @SpringBootTest, MockMvc и настройки Security. И если после этого они зелёные, это значит только то, что тесты и код договорились между собой. А вот того, что для клиентов ничего не поменялось, они не доказывают.

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

  • запросы идут через java.net.http.HttpClient из JDK;

  • состояние базы перед тестом сбрасывается обычным JDBC;

  • тесты лежат в отдельном source set src/contractTest и стучатся в уже поднятый сервис по TARGET_BASE_URL.

Контрактные тесты лежат рядом с main и test, но в отдельном source set
Контрактные тесты лежат рядом с main и test, но в отдельном source set

Каждый тест описывает то, на что рассчитывает конкретный клиент. Вот, например, чего ждёт плательщик с просроченной ссылкой.

@Test
@DisplayName("Устаревшая ссылка на оплату — 404, а не просьба залогиниться")
void expiredPaymentLinkIsNotFound() throws Exception {
    HttpResponse<String> response = api.send(api.request("/api/public/pay/expired-token").GET());

    assertEquals(404, response.statusCode(), response.body());
    assertEquals(404, json(response).path("status").asInt());
    assertEquals("/api/public/pay/expired-token", json(response).path("path").asText());
}

Всего тестов 12. Они покрывают основной сценарий со счетами, доступ и публичная ссылка, совместимость с gateway. Скрипт scripts/contract-check.sh одной командой поднимает PostgreSQL и сервис из текущей ветки, гоняет тесты и гасит сервис. Так что один и тот же набор можно запустить и на 2.7, и на 3.5. Успех.

Осталось запретить агенту подгонять тесты под новую реализацию. Это правило я записал не в промпт, а прямо в репозиторий, в AGENTS.md. Агент читает этот файл, когда начинает работу.

AGENTS.md: тесты в src/contractTest менять нельзя, при конфликте — остановиться и сообщить
AGENTS.md: тесты в src/contractTest менять нельзя, при конфликте — остановиться и сообщить

Верить агенту на слово при этом не обязательно. Достаточно убедиться, что git diff boot-2.7 -- src/contractTest пустой.

А ловят ли эти тесты вообще хоть что-нибудь? Прежде чем отдавать сервис агенту, я проверил это сам и сделал «наивную» миграцию. Поправил ровно то, на что ругался компилятор, и больше ничего. Проект собрался, сервис стартовал, health-check ответил UP, а контрактные тесты упали в 7 случаях из 12. Было 500 при выставлении счёта, 404 на списке, 401 на публичной ссылке и 400 на запросе от gateway. Наивную версию я потом выкинул, и агент получил исходный код на 2.7.

Что меняется между 2.7 и 3.x

Spring Boot 3.0 стал самым крупным релизом со времён второй версии. Ниже основные изменения, которые заденут типичный сервис. Самое важное здесь в последней колонке.

Область

Что меняется

Видно при сборке?

Java

минимальная версия — 17

да

Jakarta EE

javax.* → jakarta.*

да

Spring Security 6

удалён WebSecurityConfigurerAdapter, antMatchers → requestMatchers, по умолчанию защищены все типы dispatch, включая ERROR

частично

Spring MVC 6

слэш на конце пути больше не совпадает с маршрутом без него

нет

Hibernate 6

другие имена sequence по умолчанию, изменения в типах и HQL

нет

Конфигурация

часть свойств переименована или удалена; старые молча игнорируются

нет

Наблюдаемость

Spring Cloud Sleuth → Micrometer Tracing

да

Flyway 10+

поддержка PostgreSQL вынесена в отдельный модуль

при старте

Все подробности есть в официальном Spring Boot 3.0 Migration Guide.

Почему 3.5, а не сразу 4.x? Потому что переход 2.7 → 3.x самый тяжёлый. Jakarta, Security 6 и Hibernate 6 прилетают как раз здесь. Ветка 3.x заканчивается на 3.5, так что это логичная промежуточная остановка. Честно скажу, что и у 3.5 бесплатная поддержка уже закончилась в июне 2026 года, поэтому задерживаться на ней надолго не стоит. Про переход 3.5 → 4 расскажу в отдельной статье.

Отдаю миграцию агенту

Работал я в десктопном приложении Kodacode на модели Koda Pro с максимальным уровнем рассуждений. Проект открыл на ветке migration/boot-3.5, которую создал от тега boot-2.7, в режиме «Без подтверждений», где агент сам читает файлы, запускает команды и правит код.

Проект открыт в Kodacode, выбрана модель koda-pro
Проект открыт в Kodacode, выбрана модель koda-pro

Но сначала, прежде чем давать задачу, я задал агенту один вопрос и попросил пока ничего не трогать.

Что это за сервис и что в нём может сломаться при переходе на Spring Boot 3.5? Пока ничего не меняй.

Мне хотелось понять, что агент разглядит в коде заранее, а потом сравнить его прогноз с тем, что получится на самом деле. Думал он почти восемь минут. За это время прочитал исходники, один раз запустил команду и дважды сходил в интернет за документацией.

Ответ агента: что это за сервис и какие изменения видны при компиляции
Ответ агента: что это за сервис и какие изменения видны при компиляции

Риски он поделил на две кучки. В первую попали очевидные, на которых падает компиляция, вроде javax → jakarta, пропавшего WebSecurityConfigurerAdapter и Sleuth. Во вторую то, что он назвал «неочевидные рантайм-ловушки — именно они валят контракт», причём для каждой указал конкретный тест, который упадёт.

Таблица рантайм-ловушек: причина и тест, который упадёт
Таблица рантайм-ловушек: причина и тест, который упадёт

И попал в точку, назвав все четыре ловушки, которые я заложил в сервис.

  • Hibernate 6 ищет invoices_seq вместо hibernate_sequence → любой POST /api/invoicesдаст 500;

  • слэш на конце пути → /api/invoices/ даст 404;

  • Security 6 проверяет доступ и к /error → просроченная ссылка на оплату даст 401 вместо 404;

  • server.max-http-header-size молча игнорируется → заголовок 16 КБ даст 400.

Без промаха тоже не обошлось. Агент решил, что сломается B3-трассировка. Но об этом позже.

Варианты фикса для sequence и что пострадать не должно
Варианты фикса для sequence и что пострадать не должно

Но угадать ещё не значит смигрировать. Знать про ловушку и аккуратно обойти её в живом коде совсем не одно и то же. Так что дальше смотрю, дотянет ли агент до зелёных тестов.

Промпт получился коротким. Все требования к миграции лежат в репозитории, а не в нём. Правила работы описаны в AGENTS.md, объём и критерии приёмки в docs/MIGRATION.md. Промпт просто собирает их в задачу.

Переведи этот сервис со Spring Boot 2.7 на Spring Boot 3.5.

Сначала прочитай `AGENTS.md` и `docs/MIGRATION.md`, затем изучи код и контрактные
тесты в `src/contractTest`.

Порядок работы:

1. Запусти `scripts/contract-check.sh` на текущей версии и зафиксируй исходный результат.
2. Составь план миграции и перечисли риски.
3. Выполни миграцию.
4. Запусти `./gw build` и `scripts/contract-check.sh`.
5. Если контрактные тесты падают, найди причину и исправь код приложения.
   Тесты и их ожидания не меняй.
6. Повторяй, пока все критерии приёмки из `docs/MIGRATION.md` не выполнены.

В конце дай отчёт в формате из `docs/MIGRATION.md`.
Основной промпт отправлен в тот же чат
Основной промпт отправлен в тот же чат

Исходный прогон и план

Первым делом агент сделал то, что просили в первом пункте, и прогнал контрактные тесты на нетронутой 2.7. И тут же упёрся в реальность. Docker в окружении агента не нашёлся, потому что на машине стоит Rancher Desktop, и его docker не попал в PATH. Останавливаться и звать на помощь он не стал, а вместо этого нашёл PostgreSQL 16, установленный через Homebrew, завёл в нём роль и базу billing (и предупредил, что это меняет только локальный PostgreSQL), а ещё подсунул временную заглушку docker за пределами репозитория, чтобы скрипт проверки отработал как есть.

Docker недоступен: агент поднимает локальный PostgreSQL и фиксирует исходный результат
Docker недоступен: агент поднимает локальный PostgreSQL и фиксирует исходный результат

На 2.7 получилось 12 из 12. Дальше он набросал план из шести шагов и показал его чек-листом.

План миграции: шесть шагов, четвёртый — рантайм-совместимость
План миграции: шесть шагов, четвёртый — рантайм-совместимость

Здесь интересен четвёртый шаг «Исправить рантайм-совместимость: trailing slash, B3, размер заголовков, ERROR-dispatch, sequence Hibernate 6». То есть прогноз из первого вопроса никуда не делся. Агент сделал из него отдельный пункт плана ещё до того, как увидел хоть один красный тест.

Сборка и код

Минут через десять после старта агент добрался до build.gradle.kts. Было так.

До: Spring Boot 2.7.18, dependency-management 1.0.15, Java 11
До: Spring Boot 2.7.18, dependency-management 1.0.15, Java 11

А стало так.

После: Spring Boot 3.5.16, dependency-management 1.1.7, Java 21
После: Spring Boot 3.5.16, dependency-management 1.1.7, Java 21

Из зависимостей он выкинул BOM Spring Cloud 2021.0.9, потому что кроме Sleuth ничего из Spring Cloud в проекте не было. Место Sleuth занял Micrometer Tracing с провайдером Brave, именно туда переехало ядро Sleuth, а ещё появился модуль flyway-database-postgresql, без которого Flyway 10+ PostgreSQL просто не узнаёт. Это прямо написано в документации Spring Boot 3.5. Всё неочевидное агент подписал комментариями прямо в коде.

Зависимости после миграции: Micrometer Tracing вместо Sleuth и отдельный модуль Flyway
Зависимости после миграции: Micrometer Tracing вместо Sleuth и отдельный модуль Flyway

Потом пошла рутина. javax.* → jakarta.* в пяти файлах, SecurityFilterChain вместо WebSecurityConfigurerAdapter, новый Tracer в фильтре, который отдаёт trace id. Заодно он сразу поставил четыре защиты от рантайм-ловушек. К ним я вернусь чуть ниже, когда дойду до проверки.

Первый прогон на 3.5 зелёный, и это подозрительно

Через 14 минут после старта Kodacode собрал проект и запустил контрактные тесты на Spring Boot 3.5.16.

Первый прогон на 3.5: все 12 контрактных тестов зелёные
Первый прогон на 3.5: все 12 контрактных тестов зелёные

12 из 12 с первого раза. Вроде бы всё, пиши отчёт. Только зелёный прогон сам по себе мало о чём говорит. Может, все исправления и правда нужны. А может, половина из них лишняя, а тесты проверяют совсем не то, что я думаю.

Агент, похоже, подумал о том же и решил проверить.

Всё зелёное с первого раза. Чтобы отчёт содержал достоверные причины падений, проверю каждую защиту по отдельности — временно откатывая её и прогоняя контракт.

Я его об этом не просил. В промпте было «если тесты падают, найди причину». Тесты не упали, и агент сам себе устроил контрольный эксперимент.

Агент проверяет каждую защиту

Дальше он по очереди снимал по одной защите, прогонял контракт, записывал, какой тест упал и как, и ставил защиту на место. В отчёте из этого получилась таблица.

Таблица абляций из отчёта агента: какую защиту убрали, какой тест упал и почему
Таблица абляций из отчёта агента: какую защиту убрали, какой тест упал и почему

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

Hibernate 6 и последовательность ID

Если убрать явный @SequenceGenerator и оставить голый @GeneratedValue, падают все четыре теста, которые выставляют счёт. Они получают 500, а в логе relation "invoices_seq" does not exist.

Компилятор тут бессилен, ведь аннотация @GeneratedValue осталась ровно той же. Поменялось поведение самого Hibernate. Для стратегии AUTO Hibernate 5 брал общую последовательность hibernate_sequence, а Hibernate 6, как сказано в его руководстве по миграции, создаёт отдельную последовательность <имя сущности>_seq на каждую иерархию сущностей, причём с шагом 50, как у @SequenceGenerator по умолчанию. Схему здесь создаёт Flyway, и там есть только hibernate_sequence. При ddl-auto: none сервис спокойно стартует и падает на первой же записи.

Тот же гайд предлагает для обратной совместимости глобальную настройку hibernate.id.db_structure_naming_strategy=legacy. Агент выбрал более точечный путь. Он не стал городить новую миграцию, а просто явно указал существующую последовательность и шаг 1.

Явный @SequenceGenerator на существующую hibernate_sequence
Явный @SequenceGenerator на существующую hibernate_sequence

Потом он отдельно проверил это решение по критерию приёмки «существующая база продолжает работать». Вставил в базу строку «как из 2.7» с id=900 и убедился, что счёт читается как INV-000900, а новый получает id=901. Значит, последовательность продолжается, а не начинается с нуля.

Слэш на конце пути

Если убрать явные пути со слэшем, GET /api/invoices/ от мобильного клиента отвечает 405 Method Not Allowed.

Дело в том, что в Spring MVC 6 сопоставление со слэшем на конце отключили по умолчанию, а саму настройку объявили устаревшей. В официальном гайде описан результат 404, и при моей наивной миграции этот же запрос действительно давал 404, а при откате у агента 405. Всё потому, что POST у него уже висел и на "/". Spring находит маршрут, но не для этого метода. Причина одна, а коды ответа разные. Поэтому в контрактном тесте стоит проверять конкретный статус, а не просто «не 200».

Агент прописал пути со слэшем явно, причём на всех эндпоинтах контроллера, а не только на списке, на который жаловался тест. Так поведение 2.7 сохраняется полностью.

Явные пути "" и "/" на всех эндпоинтах контроллера
Явные пути "" и "/" на всех эндпоинтах контроллера

Security 6 и страница ошибки

Если убрать разрешение для ERROR-dispatch, плательщик с просроченной ссылкой получает 401 вместо 404.

Самое неочевидное место. permitAll для /api/public/** никуда не делся. Но контроллер бросает ResponseStatusException, контейнер внутри перенаправляет запрос на /error, а Security 6 авторизует каждый тип dispatch, включая ERROR. Об этом же говорит и гайд по миграции Boot. Анонимного пользователя до /error не пускают, и он получает 401. В 2.7 внутренний переход повторно не проверялся. Сам приём с dispatcherTypeMatchers(DispatcherType.ERROR).permitAll() есть в документации Spring Security.

Починилось одной строкой dispatcherTypeMatchers(DispatcherType.ERROR).permitAll(), и агент оставил рядом комментарий, зачем она нужна.

SecurityFilterChain: ERROR-dispatch разрешён, иначе 404 превращается в 401
SecurityFilterChain: ERROR-dispatch разрешён, иначе 404 превращается в 401

Размер заголовка

Если убрать новое свойство с размером заголовка, запрос от gateway с 16 КБ в X-Client-Context получает 400 ещё от Tomcat, до приложения он даже не доходит.

В Boot 3.0 свойство server.max-http-header-size объявили устаревшим в пользу server.max-http-request-header-size, а к 3.5 оно перестало поддерживаться совсем. Старое имя в YAML никто не проверяет. Spring молча пропускает неизвестное свойство, и Tomcat возвращается к стандартным 8 КБ.

Фикс простой, это новое имя свойства. В том же файле видна и настройка трассировки, о ней чуть позже.

application.yml: новое имя свойства и явная B3-пропагация
application.yml: новое имя свойства и явная B3-пропагация

Flyway и PostgreSQL

Пятая защита не тихая, но агент внёс в таблицу и её. Без модуля flyway-database-postgresqlсервис просто не стартует и падает с FlywayException: Unsupported Database: PostgreSQL 16.6. Такое замечаешь сразу, но понять по одной этой строке, в чём дело, получается не всегда.

Итог

Закончил агент отчётом в том формате, который просил docs/MIGRATION.md. В нём есть что изменилось, какие тесты падали и почему, результаты и что проверить не удалось.

Результаты из отчёта агента
Результаты из отчёта агента

На слово я отчёту не поверил и прогнал ключевые проверки сам.

$ ./gw clean build
BUILD SUCCESSFUL

$ ./gw contractTest
12 tests completed, 12 passed
BUILD SUCCESSFUL

$ git diff --stat boot-2.7 -- src/contractTest
(пусто)

$ git diff --stat boot-2.7
8 files changed, 68 insertions(+), 61 deletions(-)

В логе старта нет ни одной строки уровня WARN или ERROR.

Параметр

Значение

Модель

Koda Pro, максимальный уровень рассуждений

Анализ рисков (первый вопрос)

8 минут

Миграция от промпта до отчёта

24 минуты

До первого зелёного прогона на 3.5

14 минут

Изменено файлов

8, +68 / −61 строк

Контрактные тесты

12 из 12, ожидания не менялись

Вмешательств человека во время миграции

0

Что пошло не так

Агент трогает не только код, но и окружение. Когда Docker не нашёлся, он завёл роль и базу в локальном PostgreSQL и положил временную заглушку docker в /tmp. Он об этом предупредил, и всё это за пределами репозитория. Но учтите, что в режиме без подтверждений агент решает такие проблемы сам, и после сессии ваш локальный PostgreSQL будет уже не таким, как до неё. С настоящим Docker скрипт contract-check.sh он так и не проверил, о чём честно написал в отчёте.

Промах с B3. Отвечая на первый вопрос, Kodacode уверенно заявил, что Micrometer Tracing по умолчанию понимает только W3C и B3-заголовки от gateway потеряются. Это не так. В Boot 3.5 свойство management.tracing.propagation.consume по умолчанию равно [W3C, B3, B3_MULTI], то есть входящие B3-заголовки принимаются и без настройки. Хорошо, что агент сам в этом разобрался, когда откатывал защиты. Тест прошёл и без настройки, и в итоговом отчёте он прямо написал, что B3-пропагация не подтверждена падением. Хуже то, что одно промежуточное сообщение («все пять защит подтверждены реальными падениями») было неточным, и правильная картина появилась только в отчёте. Так что читайте отчёт, а не только сообщения по ходу работы.

Саму настройку propagation.type: B3_MULTI агент оставил «как декларацию требования gateway». Совсем бесполезной её не назовёшь, так сервис и дальше отдаёт B3-заголовки, как это делал Sleuth в 2.7. Но если в системе появятся клиенты с W3C traceparent, настройку придётся пересмотреть.

Что осталось на человеке. Агент ничего не закоммитил, изменения ждут ревью. А ещё он отдельно предупредил, что продовые конфиги вне репозитория не проверялись. Если spring.sleuth.* или старое server.max-http-header-size заданы в переменных окружения или ConfigMap, их надо поправить при выкатке. Иначе история с заголовком повторится, только уже в проде.

Чеклист для вашего сервиса

  1. Сначала контракт, потом миграция. Зафиксируйте поведение API внешними тестами, которые не зависят от Spring и не мигрируют вместе с кодом.

  2. Пропишите правила для агента в репозитории. Запрет трогать тесты должен лежать рядом с кодом, а не теряться в промпте. А соблюдается ли он, легко проверить через git diff.

  3. Не верьте первому зелёному прогону. Откатывайте исправления по одному и смотрите, какой тест упадёт. Если ни один, значит либо исправление лишнее, либо контракт его не покрывает.

  4. На время миграции подключите spring-boot-properties-migrator. Он подсветит переименованные и удалённые свойства, которые иначе молча игнорируются. И не забудьте про конфиги вне репозитория.

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

  6. Прогоните миграцию на копии продовой схемы. Особенно если у вас sequence и ddl-auto: none.

Вместо заключения

Я думал, что увижу, как агент спотыкается о тихие изменения Spring Boot 3 и выбирается по красным тестам. А получилось по-другому. Kodacode нашёл все ловушки ещё до миграции, закрыл их до первого прогона, а потом сам ломал каждое исправление, чтобы доказать, что оно нужно. И за всё это время в контракте не поменялось ни строчки.

Так можно ли доверить ИИ миграцию? Отдать и не смотреть точно нельзя. Агент меняет окружение, иногда уверенно ошибается и понятия не имеет, что лежит в ваших продовых конфигах. Но доверять ему на слово и не нужно. Когда есть внешний контракт, правила в репозитории и агент, который сам себя проверяет, доверие строится на проверках, а страшная миграция становится обычной задачей с понятным критерием готовности.

Демо-репозиторий с исходным сервисом, контрактными тестами и веткой после миграции лежит на github.com/befayer/spring-boot-27-migration-demo.

Что почитать

  • Spring Boot 3.0 Migration Guide, главный документ по переходу. Большинство ловушек из статьи описаны в нём.

  • Spring Security, раздел про авторизацию HTTP-запросов, где объясняется, как работают типы dispatch.

  • Hibernate ORM 6.0 Migration Guide, где описаны изменения в генерации идентификаторов.

  • Spring Cloud Sleuth 3.1 Migration Guide, про переход со Sleuth на Micrometer Tracing.

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

В следующей части переведу этот же сервис с 3.5 на Spring Boot 4.

Попробовать Kodacode можно тут: скачать для IDE, CLI и Desktop. Анонсы обновлений, практические разборы и новости продукта в Telegram‑канале.

Источник: https://habr.com/ru/companies/koda/articles/1098702/


Интересные статьи

Интересные статьи

Пандемия ковида многих убедила в эффективности удаленного формата работы. Однако у каждой организации остается свое отношение к удаленке: кто-то свободно строит международные команды, кто-то допускает...
Биты невидимы, и пиксели тоже. Если, разумеется, понимать под последними не крошечные светящиеся фрагменты изображения на экране. За задачу объяснить простым пользователям как невидимое становится вид...
Всем привет! Не так давно на работе в рамках тестирования нового бизнес-процесса мне понадобилась возможность авторизации под разными пользователями. Переход в соответствующий р...
Кто бы что ни говорил, но я считаю, что изобретение велосипедов — штука полезная. Использование готовых библиотек и фреймворков, конечно, хорошо, но порой стоит их отложить и создать ...
Предыстория Когда-то у меня возникла необходимость проверять наличие неотправленных сообщений в «1С-Битрикс: Управление сайтом» (далее Битрикс) и получать уведомления об этом. Пробле...