Будет ли код, написанный для Java 8, работать на Java 17 без изменений?

Ответ

В большинстве случаев — да, благодаря обратной совместимости JVM. Но есть критические исключения, которые могут вызвать ошибки.

Основные причины проблем при миграции с Java 8 на 17:

  1. Удалённые API: Некоторые внутренние и устаревшие (deprecated) API были окончательно удалены.
    // Java 8: Работает
    // Java 17: java.lang.UnsupportedOperationException
    sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
  2. Модульная система (Project Jigsaw): Доступ к внутренним API модулей JDK (например, com.sun.*) теперь ограничен. Требуются явные разрешения в module-info.java.
  3. Устаревшие флаги JVM: Некоторые флаги виртуальной машины были удалены.
  4. Изменения в поведении: Некоторые методы, например, в коллекциях, могут вести себя строже.

Рекомендуемые действия перед миграцией:

  • Запустите jdeprscan для поиска использования устаревших API в вашем коде и библиотеках.
  • Обновите все зависимости до версий, совместимых с Java 17.
  • Протестируйте приложение с флагом --illegal-access=warn, чтобы найти проблемы с рефлексивным доступом.
  • Используйте jlink или jpackage для создания модульного приложения.

Ответ 18+ 🔞

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

В общем-то, в большинстве случаев — да, твой старый код не сдохнет. JVM — она хитрая жопа, обратную совместимость держит крепко. Но, блядь, есть такие подводные грабли, что овердохуища. Наступишь — и привет, пиздец в продакшене.

Вот основные причины, по которым может пойти по пизде всё веселье:

  1. API, которые взяли и выпилили. Ну, знаешь, эти внутренние штуки, на которые все забивали хуй, а они тихо депрекейтились. А в семнадцатой их просто не стало.

    // На восьмёрке: летало.
    // На семнадцатой: UnsupportedOperationException, ёпта!
    sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();

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

  2. Эта ёбанная модульная система (Project Jigsaw). Она, сука, как бульдозер приехала. Раньше ты мог рефлексией лазить куда угодно, по com.sun.* шариться. А теперь — хуй там! Тебе надо в module-info.java явно разрешения выписывать, как индульгенции. Без них — стена.

  3. Флаги JVM, которые отправили на пенсию. Ты там в скриптах запуска какие-нибудь -XX:+AggressiveOpts или -XX:+UseConcMarkSweepGC оставил? Так вот, их могло и не стать. Запустишь — виртуалка тебе с порога: «Чё за хуйню ты мне подсунул?».

  4. Поведение поменялось. Где-то стали строже проверки, где-то коллекции по-другому сортируют null. Мелочь, а неприятно, как заноза в жопе.

Так и что делать-то, спросишь? Не охуевать, а готовиться.

  • Первым делом, запусти jdeprscan. Эта утилита — как металлоискатель. Прошерстит твой код и все библиотеки, найдёт все эти устаревшие API, на которые ты забил. Увидишь список — волнение ебать, но лучше сейчас, чем когда всё упало.
  • Обнови все зависимости. Твой любимый фреймворк или та библиотека для работы с JSON, которую писал один чувак в 2012 году? Убедись, что у них есть версии для 17-й. Иначе будет «ClassNotFoundException» на ровном месте.
  • Запусти тесты с флагом --illegal-access=warn. Он будет орать тебе в лог каждый раз, когда твой код или библиотеки пытаются через рефлексию пролезть куда не надо. Так ты найдёшь те самые проблемы с модулями.
  • Если уж совсем по-взрослому, посмотри на jlink или jpackage. Это чтобы собрать своё приложение со всеми нужными кусками рантайма в один красивый (и не очень) образ. Зато самодостаточный, как ёж в тумане.

Короче, миграция — это не «задеплоил и пошёл пить чай». Это как переезд на новую квартиру: если просто всё в мешки накидать и вывалить в новом месте, полгода потом искать носки будешь. Лучше разобрать по коробкам, выкинуть хлам (устаревшие API), проверить, влезает ли диван (библиотеки) в новый лифт (JVM 17). Зато потом жить будет хорошо. Ну, или терпения ноль ебать, но это уже другой разговор.