Claude CodeでStruts 1.xのAction・JSP対応表を作り修正範囲を絞る
struts-config.xmlからURL・Action・ActionForm・forward先JSPの対応表を作り、JSPを直したときに影響する画面を逆引きする手順です。
Struts 1.xの保守で最初に詰まるのは、「このJSPを直すと、どの画面が変わるのか」が分からないことです。答えは struts-config.xml とJavaソースに散らばっています。URLのpathからActionクラス、ActionForm、forward先のJSPまでを1枚の表にしておけば、JSPのファイル名から逆引きして影響範囲を出せます。Claude Codeには、この表をXMLから起こし、ソースと突き合わせて検証する作業を任せられます。
Struts 1は、Apache Strutsプロジェクトが寿命の終了(EOL)を告知したフレームワークです。最後のリリースは2008年12月の1.3.10で、重大なバグやセキュリティ問題が見つかっても新しいリリースは期待できないと告知に書かれています。それでも現場に残っている以上、直す範囲を正確に絞る技術のほうが、全面移行の議論より先に必要になります。
逆引きに必要な4つの列
対応表の列は、struts-config.xml の要素から決まります。DTD(struts-config_1_3.dtd)で各属性の意味を確かめたうえで、次の4列にそろえます。
表にする4つの情報
URLのpath
<action>のpath属性です。先頭は/で、拡張子マッピングを使う場合は拡張子を含めません。Actionクラス
<action>のtype属性です。typeの代わりにforwardかincludeを指定した定義もあり、その場合はActionクラスが存在しません。ActionForm
<action>のname属性が、<form-bean>のnameを指します。type側のクラスが実体です。forward先のJSP
<forward>のpath属性です。<action>の中に書かれたものと、<global-forwards>に書かれたものの2系統があります。
DTDには、画面の分岐に効く属性がほかにもあります。validate はActionを呼ぶ前にActionFormの validate メソッドを呼ぶかを決め、input は検証エラーのときに制御を戻す先のpathです。input は name を指定したときだけ有効です。入力エラー時に戻る画面は、正常系のforwardとは別の画面なので、表には「入力エラー時の戻り先」の列を足しておくと取りこぼしません。
例外のときの遷移先も、別の画面です。<exception> 要素の path は、その例外が起きたときにリクエストを引き取るリソース(module-relative)で、多くはエラー画面のJSPを指します。<action> の中に書けば個別のActionだけ、<global-exceptions> に書けば全体が対象で、同じ例外型ならAction側の定義が上書きします。エラー画面のJSPを直すときは、この path を引かないと影響する画面が出てきません。
forward要素には redirect 属性があり、true なら新しいリクエストを発行させ、false なら RequestDispatcher.forward が呼ばれます。リダイレクトを挟むとリクエスト属性が引き継がれないため、JSPが読む値の出どころが変わります。表のforwardの欄にredirectの有無を添えておく価値は、この違いにあります。
もう1つ、parameter 属性にも注意が要ります。DTDは、Actionクラスに追加情報を渡す汎用の設定値としか説明していません。値の意味はActionクラスの実装で決まります。呼び出すメソッド名を入れている現場もあるため、列に parameter を足し、その値をActionがどう使うかはソースで確かめます。1つのpathに複数の処理がぶら下がっている場合、そのpathは影響範囲の逆引きで重く扱う必要があります。
設定の読み方をCLAUDE.mdに固定する
毎回同じ読み方をさせるために、読み方の規則を CLAUDE.md に書きます。ベストプラクティスのページは、CLAUDE.md には「コードから読み取れないこと」だけを置くよう勧めています。具体的には、コードの見た目が紛らわしい箇所や、同じ訂正を2回したことの記録です。Strutsの設定の読み方は、まさに後者に当たります。
# Struts 1 の読み方(このリポジトリ)
- 設定ファイルは WEB-INF/struts-config*.xml。モジュールごとに分かれている
- 画面の対応表は docs/struts-map.md に置く。列は
path / Action(type) / ActionForm(name→form-bean の type) /
forward名→JSP(redirect の有無つき) / input・exception の遷移先
- <action> に type が無く forward 属性だけの定義は「Actionなし」と明記する
- <global-forwards> の forward は全 Action から使える。<action> 内に同名の
forward があればそちらが上書きする。表では別枠にして、JSP からの逆引きに含める
- <exception> と <global-exceptions> の path(エラー画面)も表に入れる
- 読んだ根拠は XML の行番号で示す。推測で埋めない全体のデータや用語を最初に把握させる使い方は、ドメイン用語集を CLAUDE.md に置く手順と同じ形です。CLAUDE.md は1ファイル200行以内が目安とされています。表そのものはここに貼らず、docs/struts-map.md のように別ファイルへ出して、必要なときに読ませます。
表を作る手順
最初に、リポジトリの全体像を聞きます。公式ドキュメントには「プロジェクトのコードベースの概要を聞く」「ドメイン用語を含めた用語集を頼む」といったプロンプトの型があります。Struts 1では、次のように設定ファイルを名指しすると話が早くなります。
WEB-INF/struts-config*.xml をすべて読んで、action 定義ごとに
path / type / name(form-bean の type まで解決)/ forward の name と path
(redirect の有無つき)/ input / exception の path を表にして docs/struts-map.md に書いて。
type が無い action は「Actionなし」と明記して。出てくる表は、たとえば次のような形になります(これは書式の例示で、実際の内容はリポジトリ次第です)。
| path | Action | ActionForm | forward(name→JSP) | input・exception先 |
|---|---|---|---|---|
| /orderEntry | ActionOrderEntryAction | ActionFormOrderForm | forward(name→JSP)success→/order/confirm.jsp | input・exception先input=/order/entry.jsp |
| /orderConfirm | ActionOrderConfirmAction | ActionFormOrderForm | forward(name→JSP)done→/order/complete.jsp(redirect) | input・exception先input=/order/confirm.jsp、exception=/error/stock.jsp |
| /login | ActionLoginAction | ActionFormLoginForm | forward(name→JSP)success→/menu.jsp | input・exception先input=/login.jsp |
この例では、OrderForm が2つのactionで共有されています。ActionFormを共有する画面は、フォームのプロパティを変えたときに両方が影響を受けるので、後の逆引きで必ず効いてきます。
設定とソースを突き合わせる
XMLだけで表を閉じず、ソースとも突き合わせます。ActionのJavaソースは、mapping.findForward("success") のように論理名で遷移先を呼びます。設定にforward名が書かれていても、ソースが呼ばない名前なら死んだ定義です。逆に、ソースが呼ぶ名前が設定のどこにも無いなら、<global-forwards> に頼っているか、実行時に例外になる状態です。
docs/struts-map.md の各行について、Action の execute メソッドが
呼ぶ findForward の引数をすべて列挙して。表の forward 名と比べて、
(1)表にあってソースが呼ばない名前 (2)ソースが呼ぶのに表にも
global-forwards にも無い名前 を、ファイルと行番号つきで出して。数十のActionを一度に読むと、会話のコンテキストがファイルの中身で埋まります。探索をサブエージェントに任せると、読んだファイルが自分の会話に積まれずに要約だけが返ります。組み込みの探索用サブエージェントは読み取り専用で、WriteとEditが禁止されています。突き合わせの前半は、次のように頼めます。
サブエージェントで、com.example.web.action 配下の全 Action について
findForward の引数を調べて、Action名 → 論理名の一覧だけ返して。JSPから影響範囲を逆引きする
表ができたら、本題の逆引きです。JSPのファイル名を入力にして、そのJSPを表示する画面を探します。
JSPを直す前の確認の順番
- 1
forward先の列を引く
表のforward先の列に、そのJSPのpathがあるかを見ます。あれば、その行のpathが「そのJSPを出すURL」です。1行ごとにURLを控えます。
- 2
global-forwardsを引く
<global-forwards>のpathにそのJSPがあれば、同名のforwardを<action>内に持たないactionすべてが対象です。ソースが呼ぶ論理名で絞り込みます。 - 3
exceptionのpathを引く
そのJSPがエラー画面なら、
<exception>と<global-exceptions>のpathを引きます。該当する例外型を受けるactionが、影響を受ける画面です。 - 4
includeしている側を引く
jsp:includeや<%@ include %>の取り込み先を検索します。部品JSPは、取り込んでいるすべての画面に効きます。 - 5
対象リストを確定する
ここまでに出たURLの一覧が、動作確認の対象です。ActionFormを共有するactionは、プロパティを変えるときだけ対象に加えます。
4つ目の確認(includeしている側を引く手順)は、struts-config.xml を読むだけでは出てきません。JSPの中のインクルードは設定ファイルの外にあるため、grepで確かめます。Tilesのようなレイアウト機構を使っている場合は、tiles-defs.xml のような別の定義ファイルに、画面を構成するJSPが書かれていることがあります。表の「forward先」がJSPではなくTilesの定義名になっているときは、その先の定義ファイルまで追って、実際のJSPに解決した列を足します。
次のように頼めば、確認を1回のプロンプトにまとめられます。
WEB-INF/jsp/order/confirm.jsp を修正する予定。docs/struts-map.md と
ソースから、(1)このJSPを forward 先に持つ path (2)global-forwards
経由で到達する path (3)このJSPを include している別JSP とその先の
path (4)exception / global-exceptions の path にこのJSPを持つ action
を洗い出して、画面確認の対象リストにして。根拠の行番号も付けて。表の誤りを人が確かめる箇所
表が正しいかどうかは、自動では保証されません。次の点を、サンプルの数行について人が見ておくと、誤読が早く見つかります。
<form-bean>のtypeが、実在するクラスにたどり着いているか。nameが同じ別定義を取り違えていないか<action>内のforwardと<global-forwards>で同名のものがあるとき、action側が優先されているか。DTDは、actionが同名のローカルなforwardを定義するとglobal forwardを上書きできると説明しています。exceptionも同様です- モジュール分割をしている場合、pathが「モジュール相対」である点。DTDはforwardやactionのpathを「module-relative」と説明しています。複数の設定ファイルがあるなら、表にモジュール名の列を足します
表の全行を読むのではなく、サンプルの行を検算する。この確認ひとつで、読み方の規則の漏れが分かります。見つかった誤りは、同じ訂正を繰り返さないよう CLAUDE.md の規則に書き足します。
表を最新に保つ
対応表は、設定を直すたびに古くなります。再生成を一行で呼べるように、非対話モードで回す形にしておきます。公式は claude -p "prompt" を、1回実行して終了する形としてCIやgit hookに載せる使い方で紹介しています。
claude -p "WEB-INF/struts-config*.xml から docs/struts-map.md を
CLAUDE.md の規則どおりに再生成して" \
--allowedTools "Read,Glob,Grep,Write,Edit"設定ファイルを変更するプルリクエストで再生成を走らせ、差分を表の更新としてレビューすれば、対応表が保守のたびに壊れることを避けられます。
注意: 表は調査の入口であって保証ではない
この表は、設定ファイルとソースに書かれたことだけを写しています。実行時に動く仕組みは写せません。たとえば、Actionが動的に決めた遷移先や、フィルタやインターセプタ的な処理が挟む分岐です。動作確認の対象リストが「必要十分」であるとは言えず、「最低限これは見る」の一覧です。
もうひとつ、画面の見た目の崩れは表から読めません。JSPやCSSを直した結果を目で確かめたい場合は、Playwrightのスクリーンショット比較で、対象リストの画面を直す前後で撮って比べる手があります。
まとめ
Struts 1の保守は、「何を直すか」より「どこまで波及するか」を先に決めると進めやすくなります。struts-config.xml の action・form-bean・forward を1枚の表にし、JSPの名前から逆引きできる状態を作る。読み方の規則を CLAUDE.md に書いておけば、Claude Codeは毎回同じ列で表を出します。ソースの findForward との突き合わせまで済ませた表が、JSP修正のたびに確認すべき画面の一覧になります。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。