☕️

プロダクトの Java を 8 → 17 へバージョンアップしたときにやったこと

2023/12/24に公開

こんにちはー。
BABY JOB 株式会社の @mackey0225 です!

もうクリスマスイブですよ。年の瀬ですよ。本当にあっという間の一年でした。
個人的には、今年は JJUG CCC に春・秋と出れたことは非常に嬉しく、自分の成長に繋がりましたね。

そこで今回は JJUG CCC 2023 Fall で話せなかった Java バージョンアップに関する運用面について記事にしようと思います。

執筆の背景

先にも書きましたが、
2023 年の 11 月に開催された JJUG CCC 2023 Fall に以下の内容で登壇しました。
https://speakerdeck.com/mackey0225/20231111-key-implementation-points-from-java-8-to-21

上記の発表では、Java のバージョンアップに伴う 「実装」 で使えそうな新機能を紹介したり、プロダクト内での使用例やイメージについて話をしました。
逆に、チームとしての運用やバージョンアップの取り組みについては話をしなかったので、当日の発表でも質問をいくつか頂きました。
つまり、質問があることは価値があると考え、この記事を書いてみました![1]

本記事の概要

この記事では大きく以下についてまとめます。

  • Java のバージョンを上げた際にやったこと
  • やっていった中での苦労話

バージョンアップでやったこと

大きくは以下の点について実施しました。

  • バージョンアップに伴う影響の確認と改修
  • チーム内への展開
  • CI/CD パイプラインを含むプロダクトへの適用

バージョンアップに伴う影響の確認と改修

バージョンアップに関して以下の2つを確認し、プロダクトへの影響を調査しました。

  • 各バージョンでの機能の確認
  • 非推奨要素の確認

各バージョンでの機能の確認

OpenJDK 内で提供されている各JDK の機能一覧を参考にしました。
下記の例の様に、バージョンごとに取り込まれた機能を JEP(JDK Enhancement Proposal)の単位で一覧になっており、それを確認しました。

例 Java 21 で取り込まれた機能一覧

https://openjdk.org/projects/jdk/21/

非推奨要素の確認

Oracle が提供している Java SE に関する資料を参考にしました。

Java 21 までに非推奨になった要素一覧

Removed APIs

https://docs.oracle.com/en/java/javase/21/migrate/removed-apis.html

Removed Tools and Components

https://docs.oracle.com/en/java/javase/21/migrate/removed-tools-and-components.html

上記の確認した内容を元に、必要に応じて改修を行うことでプロダクトとして問題ない状態にしました。

チーム内への展開

各メンバーの環境も合わせて、横展開が必要になりますので、手順書の作成とその説明を行いました。

また、工夫・意識した点は、

  • バックエンドのメンバーだけでなくデザイナーメンバーもいるので、手順に落とし込む際に言葉や手順の粒度を慎重に選ぶこと
  • チームや関わるメンバーに対して、常日頃から状況の共有を行い、スムーズに進められるように連携したこと

CI/CD パイプラインを含むプロダクトへの適用

本番の稼働環境のランタイムだけでなく、ビルドを行う CI/CD における JDK も変更対象になります。
上記のチーム内の展開とスケジュール調整をして、チームでは以下のような流れで行いました。[2]

  1. イテレーションでの成果物の確定後、速やかにチームへの手順の展開
  2. 併せて、Java バージョンアップに関する資材を次イテレーションの成果物に入るよう develop ブランチにマージ
  3. 各メンバーで Java 17 上で開発をして、問題や気になる部分が無いかを試してもらう
  4. バージョンアップした資材が成果物に含まれ、本番稼働環境全体で Java 17 として稼働する

先に稼働環境やビルドのバージョンを上げた場合、
各メンバーの開発環境は Java 17 ではないので、イテレーション内での成果物で Java 17 において避けるべき実装ができる可能性があります。[3]
そうした実装による予期せぬ不具合を避けたかったため、上記の手順で進めました。

苦労話

サービス稼働に関しては問題はなかったですが、細かい部分で苦労がありました。

使用している端末そのものやその OS での差分に苦労した

弊社は入社時に、Windows と Mac のどちらかを開発端末として選べます。
また、参画タイミングによっては、開発環境の構築手順が異なっていたりするため、
各端末によって Java (JDK) の指定方法が異なっていたことがありました。

そのため、手順書作成時は事前に関わっているメンバーにリハーサルをしてもらったり、
手順展開後に追加で修正したりなどして、環境差分を埋めることに苦労しました。

ログの出方が変わったため、運用の一部に影響があった

Java 8 → 17 にあげることで以下の機能変更がありました。

JEP 358: Helpful NullPointerExceptions
https://openjdk.org/jeps/358

こちらは、NullPointerExceptions が発生時のメッセージが細かく表現されるものです。

運用で例外やエラー発生時のログを確認していましたので、バージョンアップ後に出力されたメッセージが以前とフォーマットが違うことで、すこし混乱が発生しました。
実装やコード上で必要な変更に注視していましたが、ログの形式などの振る舞いが変わることでの影響があることは個人的な学びになりました。

さいごに

今回は Java 17 に上げましたが、 Java 21 もすでに出ており、進化し続けていますので、
負荷を掛けず、継続して運用していけるように進めていきたいです。

また、もう少し踏み込んだことを聞きたい方はコメントいただけますと、何かしらの回答はしたいと思っています。

脚注
  1. というか、こっちに興味がある人が多かったかも。。。 ↩︎

  2. 前提としては、GitFlow ワークフローをベースとしたブランチ運用をしております。GitFlow ワークフローとは?についてはこちらをご参照ください。 ↩︎

  3. 後方互換性が高いので、そもそも、そんなケースが多くないというのもありますが。。。 ↩︎

BABYJOB テックブログ

Discussion