◀ 5.

Struts パスに対するアクションのインスタンスがありません の対処

▶
この記事の要点
  • パス "..." に対するアクションのインスタンスを取得できません はStruts 1でActionの取得・生成に失敗したエラー
  • 原因 ①: Action クラスのパスが struts-config.xml と一致しない
  • 原因 ②: Action クラスのコンパイル失敗・classpath 漏れ
  • 原因 ③: パッケージ移動でクラス名のフルパス変更を反映していない
  • 対処: struts-config.xml の <action type="..." > のクラス名を確認

 

Actionの生成失敗は、クラス名や配備だけでなく、継承・コンストラクタ・生成中の例外でも起こります。フォーム定義の検索失敗やexecute内の例外とは調査対象が異なります。以下は保守終了したStruts 1の既存システム向けです。

フォーム設定、Action生成、execute実行の診断対象の違い

エラーの状況

旧例の訂正: 次のブロックにあるCannot retrieve definition for form beanは、Action生成エラーの英語訳ではありません。フォーム設定を調べる別のメッセージです。比較用に元の記録を残していますが、二つを同じ原因として扱わないでください。

javax.servlet.ServletException: パス "/login" に対するアクションのインスタンスを取得できません。

# 英語版
Cannot retrieve definition for form bean null on action /login

# または
Cannot create instance of action class for path /login

Struts 1 の ActionServlet がリクエストを処理する際、struts-config.xml で指定された Action クラスを生成できなかったエラー。

原因と対処

原因 1: Action クラスが見つからない

<!-- struts-config.xml -->
<action-mappings>
    <action path="/login"
            type="com.example.LoginAction">  <!-- ← このクラスがない -->
        <forward name="success" path="/home.jsp"/>
    </action>
</action-mappings>

確認:

  • com/example/LoginAction.class が配備済みのWEB-INF/classes/配下、またはWEB-INF/lib/のJAR内にあるか。IDE内のソースの存在だけでは判断しない
  • Maven 等でビルドし忘れていないか
  • ビルド結果と稼働中の配備先・版を照合する。クリーンビルドは成果物を確認したうえで必要な場合に実施し、削除や再起動を最初の対処にしない

原因 2: クラス名のタイポ / パッケージ違い

<!-- 修正前 -->
<action path="/login" type="com.example.LogginAction">  <!-- ← typo: Loggin -->

<!-- 修正後 -->
<action path="/login" type="com.example.LoginAction">

原因 3: Action クラスのコンストラクタや継承

Struts 1.3.10の標準RequestProcessorによる直接生成では、アクセス可能な具象クラス・引数なし生成・Actionへの型変換が必要です。独自RequestProcessorやSpringへの委譲では生成経路を別に確認します。下の上段はexecuteの戻り値を省略した説明用断片で、そのままではコンパイルできません。下段は継承とコンストラクタの二つの問題を含んでいます。

// 必須: 引数なしコンストラクタ + Action 継承
public class LoginAction extends Action {
    // 暗黙のデフォルトコンストラクタで OK

    @Override
    public ActionForward execute(
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        // ...
    }
}

// ダメな例
public class LoginAction {  // ← Action を継承していない
    public LoginAction(String name) { }  // ← 引数ありコンストラクタしかない
}

原因 4: パッケージリネーム後の反映漏れ

IDE でパッケージをリネームしたとき、Java コードはリファクタリングされても XML はそのままになることがあります:

<!-- リネーム前 com.example.controller.LoginAction -->
<!-- リネーム後 com.example.action.LoginAction に変更したのに -->

<action path="/login" type="com.example.controller.LoginAction">  <!-- ← 古いまま -->

<!-- 修正 -->
<action path="/login" type="com.example.action.LoginAction">

原因 5: WEB-INF/lib に依存 jar 不足

Action クラスがサードパーティクラスを使っている場合、その jar がないとクラスロードに失敗:

# WEB-INF/lib にすべての依存 jar があるか確認
$ ls WEB-INF/lib/
struts.jar
commons-beanutils.jar
commons-logging.jar
...

調査の手順

  1. サーバーログを確認: Action生成のエラーと同時刻の例外名・最初のアプリ側フレームを確認する。$CATALINA_HOME/logs/localhost.YYYY-MM-DD.logは一例であり、CATALINA_BASE、logging.properties、標準出力の収集方法により保存先は異なる。認証情報や要求値は共有時に伏せる
  2. クラスファイルの存在確認: WEB-INF/classes/<package>/<ClassName>.class
  3. struts-config.xml の type 属性とクラス名一致
  4. 成果物を照合: class/JARの格納先、実際のWAR、依存ライブラリと対象版を確認する。必要な修正は検証環境で再ビルドする
  5. 正式な再配備と再確認: 稼働版が切り替わったことを確認し、同じ要求とログを再確認する。再起動だけで設定・依存関係の誤りは直らない。work等の削除を通常手順にしない

標準的な Action クラスのテンプレート

認証実装として使わないでください。 元の下記コードはisValidUserが常にtrueを返す仮実装で、任意の入力を成功扱いします。Actionの構造を見る参考例に限ります。LoginForm・forwardの設定も別途必要で、クラス生成成功は認証成功の証明ではありません。実システムの既存の認証・認可・セッション管理をこの仮コードで置き換えないでください。

package com.example;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

public class LoginAction extends Action {

    @Override
    public ActionForward execute(
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        LoginForm loginForm = (LoginForm) form;

        if (isValidUser(loginForm.getUsername(), loginForm.getPassword())) {
            return mapping.findForward("success");
        } else {
            return mapping.findForward("failure");
        }
    }

    private boolean isValidUser(String username, String password) {
        // 認証ロジック
        return true;
    }
}

Struts 1 vs モダンフレームワーク

Struts 1 は2013 年でサポート終了のレガシーフレームワーク。新規開発では Spring MVC / Spring Boot を推奨。Struts 1 の保守をする場合のみこの記事の内容が必要です。

関連記事

例外名から調べる対象を絞る

確認した例外・状態次に確認すること
ClassNotFoundExceptiontypeの完全修飾名と稼働成果物のclass/JAR。パッケージ名の大小文字も一致させる。
InstantiationException / IllegalAccessException抽象クラス、引数なしコンストラクタ、クラスとコンストラクタの公開範囲。
ClassCastException指定したクラスがActionを継承しているか。依存JARの重複やクラスローダ差も必要に応じて調べる。
コンストラクタ内の例外初期化処理で失敗した箇所。クラス名が正しくても生成は失敗する。
execute内での例外生成後の入力処理・サービス・DB・遷移先。生成エラーと混同しない。

依存クラス不足はNoClassDefFoundErrorなど別の形でも現れます。RequestProcessorの生成部が捕捉するExceptionとErrorは同じではなく、すべての依存不足で同じ画面メッセージになるとは限りません。

生成成功後の注意と検証範囲

標準RequestProcessorは生成したActionをクラス名で保持します。同じprocessor内では別のpathでも同一typeのインスタンスを再利用するため、要求・フォーム・ユーザーの値をActionのインスタンス変数へ保存しないでください。要求ごとの値はexecuteの引数やローカル変数で扱います。

Struts 1.3.10の生成処理で、存在しないクラス、非Action、引数なし生成不可、抽象クラス、コンストラクタ内例外を独立に確認しました。生成成功とexecute失敗、同じtypeの再利用も分けて確認しています。Tomcat/JSP全体の配備や個別環境の障害原因を再現したものではありません。

一次資料: Apache Struts 1.3.10公式ソース配布(RequestProcessor / RequestUtils)、ApacheのStruts 1保守終了案内。関連する設定とフォーム定義は下の既存記事から確認できます。

子ページ

子ページはありません

同階層のページ
  1. createActionFormにてNullPointerException
  2. java.lang.NullPointerException: Module 'null' not found
  3. javax.servlet.jsp.JspException: Cannot find bean org.apache.struts.taglib.html.BEAN in any scope
  4. Description Resource Path Location Type cvc-complex-type.2.4.a: Invalid content was found starting with element 'X'
  5. パス ... に対するアクションのインスタンスがありません
  6. TLDによると、タグ form の属性 id は無効です