◀ 3.

Cannot find bean in any scope (Struts) エラー対処

▶
この記事の要点
  • Struts 1 の JSP で <html:text> などのフォーム部品タグを使ったときに出るエラー
  • 典型的な確認対象は、フォーム部品タグを <html:form> の外に書いていること
  • <html:form> は開始タグでフォーム Bean を「org.apache.struts.taglib.html.BEAN」という名前でリクエストスコープに置き、終了タグで取り除く。中のタグはそれを探す
  • Tiles やインクルードで部品を別 JSP に分けたとき、その JSP がフォームの範囲外で読み込まれていると同じエラーになる
  • 対処: タグを <html:form> 内に移す、または name 属性で Bean 名を明示する

このエラーは、Strutsの入力タグが値を読み出すためのBeanを見つけられないことを表します。フォームとの位置関係に加え、参照するBean名とスコープを確認してください。以下はStruts 1の既存システム保守向けです。Struts 1は保守終了しており、新規導入は勧めません。

html form開始時のBean公開、入力タグの参照、終了時のBEANキー除去と送信先の違い

エラー内容

javax.servlet.jsp.JspException: Cannot find bean org.apache.struts.taglib.html.BEAN in any scope

Struts 1 系(1.2 / 1.3)を使った JSP を表示したときに発生し、画面には HTTP 500 エラーとスタックトレースが表示されます。Tomcat などのログには、どの JSP の何行目で例外が起きたかが出力されるので、まずその行のタグを確認します。

発生条件と原因

html:formの外に、値を参照するhtml:textなどを置くことは典型例です。直接の条件は、タグが参照するBeanを見つけられないことです。タグの種類・value指定・name指定によって値の取得経路が異なるため、「フォーム外ならどのタグも必ずこのエラー」と一般化しないでください。

なぜ html:form の外だとエラーになるのか

Struts 1 の <html:form> タグは、開始タグの処理で次のことを行います。

  1. action 属性のパスから struts-config.xml のアクション定義を探す
  2. そのアクションに紐づくフォーム Bean(ActionForm)をリクエストやセッションから取得し、無ければ生成する
  3. 取得したフォーム Bean を、org.apache.struts.taglib.html.BEAN という名前でリクエストスコープに格納する(終了タグ </html:form> の処理で取り除かれる)

<html:text>、<html:password>、<html:checkbox>、<html:select> などのフォーム部品タグは、name 属性を省略すると、この「org.apache.struts.taglib.html.BEAN」を探して値を取り出します。<html:form> の外ではこの Bean がまだ置かれていない(または終了タグで取り除かれた)ため、「どのスコープにも見つからない」というエラーになります。

原因の一覧

原因確認ポイント
フォーム部品タグが <html:form> の外にあるエラー行のタグが </html:form> より後ろ、または <html:form> より前にないか
インクルードした JSP や Tiles のタイルにフォーム部品があるそのタイル・インクルードが <html:form> の開始タグと終了タグの間で読み込まれているか(ヘッダーやサイドバーのタイルに入力欄を置くと範囲外になりやすい)
JSPタグやテンプレートの実行順が想定と異なるテーブルやカスタムタグの途中で </html:form> が閉じられていないか。ブラウザが生成後のHTMLを補正する問題と、サーバー側JSPタグの実行順は分けて確認する

対処法

1. フォーム部品タグを html:form の中に移す

html:text のようなタグは、html:form タグの内側に記述します。

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<!-- NG: html:form の外にある -->
<html:text property="userId" />
<html:form action="/login">
  <html:password property="password" />
  <html:submit value="ログイン" />
</html:form>

<!-- OK: すべて html:form の中 -->
<html:form action="/login">
  <html:text property="userId" />
  <html:password property="password" />
  <html:submit value="ログイン" />
</html:form>

taglib の uri は Struts 1.3 の例です。1.2 以前では /WEB-INF/struts-html.tld のように TLD ファイルを指定している場合もあります。

2. 分割した JSP はフォームの範囲内で読み込む

入力欄を共通部品として別 JSP や Tiles のタイルに切り出している場合は、その読み込み(<jsp:include>、<tiles:insert> など)を <html:form> と </html:form> の間に置きます。フォーム全体をレイアウトの外に出すより、フォームを 1 つのタイルにまとめて、その中で入力欄を組み立てる方が構造が分かりやすくなります。

3. name 属性で Bean を明示する

どうしても <html:form> の外で値を表示したい場合は、name 属性でスコープ上の Bean の名前(struts-config.xml の form-bean の name)を明示します。こうすると BEAN キーではなく指定した名前の Bean を探します。この場合、その Bean がリクエストまたはセッションに存在している必要があります。

<html:text name="loginForm" property="userId" />

値を表示するだけで入力欄が不要なら、<bean:write name="loginForm" property="userId" /> を使う方が意図に合っています。

よく似たエラーとの見分け方

<html:form> 自体の設定に問題があるときは、このエラーではなく別のメッセージになります。エラーメッセージの文言で切り分けると原因に早くたどり着けます。

メッセージ主な原因
Cannot find bean org.apache.struts.taglib.html.BEAN in any scopeフォーム部品タグが <html:form> の範囲外にある(この記事)
Cannot retrieve mapping for action ...<html:form> の action 属性のパスが struts-config.xml の action 定義に存在しない
Cannot retrieve definition for form bean ...action 定義の name 属性で指定したフォーム Bean が form-beans に定義されていない
Cannot find bean ... in any scope(BEAN 以外の名前)<bean:write> などの name 属性で指定した Bean がリクエストやセッションに無い。Action クラスで request.setAttribute() しているか確認する

最後の行のように、BEAN以外の名前が表示される場合は、その名前・スコープに実際のBeanがあるか確認します。Actionで用意していない場合のほか、名前の誤記、別スコープ、redirect後に要求の属性が引き継がれない場合などもあり、一つの原因に断定しません。画面に直接アクセスした(.do を経由せず JSP の URL を開いた)ために Action が実行されていない、というケースもよくあります。

確認方法

  1. ログのスタックトレースで、エラーが出た JSP のファイル名と行番号を確認する
  2. その行のタグと、<html:form> の開始・終了位置の関係を確認する(インクルード元・先の両方)
  3. 修正後、アプリケーションサーバーを再起動するか JSP の再コンパイルを待ってから再表示する
  4. 表示が変わらない場合は、配備先・稼働中の版・対象JSPの再コンパイル結果を先に確認する。Tomcatのworkディレクトリ削除は通常の診断手順にしない。再配備や作業ディレクトリの整理が必要な場合は、バックアップと影響範囲を確認した正式な保守手順に従う

補足: Struts 1 の現状

Struts 1 は 2013 年にサポート終了(End of Life)が告知されており、セキュリティ修正は提供されていません。既存システムの保守でこのエラーに出会うことが多いはずですが、改修の機会があれば Spring MVC など保守されているフレームワークへの移行も検討してください。

nameとpropertyを指定するときの注意

上のloginForm例で、nameは表示値を読むBeanの参照名です。この属性を付けてもBeanが自動で用意されたり、Actionのフォーム設定や送信先が切り替わったりするわけではありません。通常の非indexedなhtml:textでは、生成されるinputのnameはpropertyのuserIdです。送信先は親formのactionで決まり、受け取るAction側のform-bean・プロパティ・検証・認可は別に照合します。

フォーム外でnameを明示してエラーが消えても、その入力欄が意図したHTMLフォームから送信されるかは確認が必要です。表示だけが目的なら既存例のbean:writeを使う意図を検討します。ただし表示専用タグでも参照するBeanと読み取り可能なプロパティは必要です。内部のBEANキーへ手動で属性を置いて症状だけを隠す対処は勧めません。

元のBeanと一時的なBEANキーは別

Actionの設定がsessionスコープでも、html:formは取得したBeanへの別名を要求のBEANキーに置きます。終了時にそのキーが取り除かれることと、元のloginForm等の名前のBean自体が消えることは同じではありません。分割JSPの見た目だけで判断せず、どの要求・スコープで、どの順序にタグが実行されるかを確認してください。

Bean未検出とプロパティ未検出を分ける

Beanは存在するのにpropertyが誤っている場合、Struts 1.3.10の検証ではgetterが見つからない別のエラーになりました。Bean名、property、Javaのgetterを大文字小文字まで照合します。明示的なvalueを使うhtml:textはBean値の取得を通らない場合もありますが、これはフォーム構成や入力検証を直す代わりにはなりません。

修正後の確認

  • 初回表示だけでなく、入力エラーで同じ画面へ戻る場合と、redirectを挟む場合を別に確認します。
  • 入力値を送信し、期待するActionとプロパティへ届くかを確認します。画面表示成功をDB保存や認可の成功と扱いません。
  • ログ共有時は入力値や認証情報を伏せます。旧版ライブラリの設定変更・再配備は検証環境で確認してから行います。

検証範囲と一次資料

Struts 1.3.10のTagUtils、FormTag、TextTagの単体検証で、既定BEANの未検出、要求/セッションの既存Beanからの別名公開、明示nameの未検出、property未検出、value指定時の取得省略、nameと送信項目名の違いを確認しました。1.3.10の実際の文言にはBean名の前のコロンと引用符が入ります。掲載の短いエラー表記は旧例として保持しています。

ServletContextとPageContextは合成検体です。Tomcat上のJSP/Tiles全体、実際のフォーム送信・認証・DB更新、Struts 1.2を含む全版の動作保証ではありません。一次資料(2026年10月確認):Struts 1.3.10 taglib公式ソース(sources JAR)。対象版の実装を照合してください。

関連

子ページ

子ページはありません

同階層のページ
  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 は無効です