移行の見積もりを求められた際、struts.xmlのアクション数を数えるだけでは規模を測れないと痛感したことがあります。ビジネスロジックがどれだけアクションクラスに埋まっているか、その分離度こそが移行コストを左右すると気づいてからの整理です。
ステップ1:現行システムの評価
図1: 段階移行・共存・落とし穴を含む移行ステップ
移行は「現状把握」から始まります。やみくもに書き直す前に、現行 Struts アプリの規模と健全性を測ります。
| 評価項目 | 見るもの |
|---|---|
| 規模 | アクション数(struts.xml/設定のマッピング数)、画面数、画面遷移の複雑さ。 |
| 結合度 | ビジネスロジックがアクションクラスに埋まっているか、サービス層に分離されているか。 |
| ビュー | JSP の量、カスタムタグ・Struts タグの利用度。HTML化の手間に直結する。 |
| 依存ライブラリ | Struts に密結合した古いライブラリ、EOL の依存物。 |
| テスト | 自動テストの有無。これが移行時の安全網になる。 |
💡 ロジックの分離度が移行コストを決める
ビジネスロジックがアクションクラスから分離され、サービス層にまとまっているほど移行は楽です。逆にアクションにロジックが溶け込んでいると、移行は「書き直し」に近づきます。評価の最優先項目はここです。
ステップ2:段階移行 vs 全面刷新
移行アプローチは大きく2つ。どちらを取るかは規模とリスク許容度で決めます。
| 条件 | 向くアプローチ |
|---|---|
| 大規模・稼働中・止められない | 段階移行 |
| 小規模・画面数が少ない | 全面刷新も可 |
| 仕様がブラックボックス化 | 段階移行(挙動を保ちつつ) |
| そもそも要件から作り直したい | 全面刷新 |
ステップ3:共存のさせ方
段階移行では、移行期間中に Struts と新フレームワークを共存させます。代表的な手法は次のとおりです。
- リバースプロキシで振り分け:URL パス単位で、移行済み画面は新アプリへ、未移行は Struts へルーティング(ストラングラーファサード)。最も疎結合で安全。
- 同一アプリ内での共存:同じ WAR / デプロイ単位に Struts と Spring を同居させ、段階的にアクションを置き換える。小〜中規模向け。
- セッション・認証の共有:共存期間中はログイン状態の引き継ぎが課題。SSO やセッション共有の設計が必要。
⚠️ 共存は「一時的な状態」と割り切る
共存は移行を安全にする手段であって、ゴールではありません。共存期間が長引くと、2つのフレームワークを同時に保守する負担が常態化します。移行の期限とマイルストーンを最初に決めることが成功の条件です。
ステップ4:移行の進め方
段階移行の典型的な順序です。
- 安全網を作る:移行前に、現行の挙動を固定する自動テスト(E2E・画面の入出力)を用意する。
- ロジックを分離する:アクションクラスに埋まったビジネスロジックを、フレームワーク非依存のサービス層へ抜き出す。これは Struts のままでも進められる。
- リスクの低い画面から移す:参照系・独立性の高い画面を新フレームワーク(Spring Boot+Thymeleaf)で再実装し、プロキシで切り替える。
- 共通基盤を移す:認証・共通レイアウト・エラー処理など横断機能を新側に集約する。
- 更新系・複雑な画面を移す:トランザクションや業務ロジックの重い画面を慎重に移行する。
- Struts を撤去する:全画面の移行後、Struts 依存とプロキシの分岐を削除して完了。
移行の落とし穴
| 落とし穴 | 対策 |
|---|---|
| 「ついでに機能追加」で肥大化 | 移行と機能改修を分ける。まず挙動を保ったまま移し、改修は後で。 |
| JSP の独自タグ資産の移植漏れ | Struts/JSPタグを Thymeleaf の部品(fragment)へ対応付けする棚卸しを先に行う。 |
| セッション・認証の不整合 | 共存期間の認証設計を最初に決める。後付けはトラブルの温床。 |
| テストがなく「動いていたはず」を壊す | ステップ1で安全網を必ず用意する。 |
| 共存の長期化 | 期限とマイルストーンを引き、定期的に進捗を可視化する。 |
Struts移行でよくある失敗パターン
移行プロジェクトには「完了させたつもりが穴だらけ」になるパターンがある。事前に知っておくだけで回避率が大きく上がる。
| 失敗パターン | 何が起きるか | 防止策 |
|---|---|---|
| 移行と同時に機能追加を混ぜる | 不具合の原因が「移行による挙動変化」か「新機能のバグ」か判別できなくなる | 移行フェーズでは挙動をそのまま移すことだけに集中し、機能追加は移行完了後に行う |
| 安全網(自動テスト)なしで移行を始める | 既存挙動を壊しても気づかないまま進み、リリース後に本番障害が多発する | 移行前にE2E・ユニットテストを最低限用意し、挙動を固定してから移し始める |
| 共存期間に期限を設けない | Struts と新世代が混在した状態が数年続き、認証・セッション管理が二重管理になる | 共存開始時点でフル移行の期限とマイルストーンを確定し、定期的に進捗を可視化する |