m2eclipse+WST+Tomcatで開発するときの落とし穴
- Java SE 6.0 + Servlet 2.5 + JSP 2.1
- Eclipse 3.4.2 (Pleiades 1.3.1)
- m2eclipse 0.9.8
- WST 3.0.4
- Tomcat 6.0.18
みたいな環境でStruts2を使ったWebアプリケーションを開発していて、意味不明なエラーに遭遇する。
こんな感じの、何の変哲もないJSPを表示しようとすると、
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <body> <s:form action="login"> <s:textfield name="username" /> <s:password name="password" /> <s:submit /> </s:form> </body> </html>
org.apache.jasper.JasperException: /WEB-INF/jsp/index.jsp(5,0) s:form タグはそれがdynamic属性を受け付けると宣言していますが、それに必要なインタフェースを実装していません
というエラーが出る。FormTag クラスを確認してもきちんと DynamicAttributes を implement しているのに何故?
検索しても類似の問題は見つからないので、仕方なく自分で考える。この手の「存在するはずのクラスが無いと言われる」のはクラスローディングの問題っぽいので、なんとなくWSTがWebアプリを配備する ${workspace}/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/アプリケーション名/ あたりを見てみたら、WEB-INF/lib に何故か jsp-api-2.1.jar やら servlet-api-2.5.jar やらのjarファイルが見つかる。
原因判明。Tomcatは自前で持っている jsp-api.jar からロードした DynamicAttributes を使って「インタフェースを実装しているか?」を判断しようとしたけど、Webアプリ側は、Webアプリ用のクラスローダが WEB-INF/lib/jsp-api-2.1.jar からロードした DynamicAttributes を「実装している」と言明していたという話。
で、そもそも何故 WEB-INF/lib にこんなjarが混じってしまったかというと、m2eclipse?の仕様だかバグだか知らないが、pom.xml で scope を provided にしているライブラリもお構いなしに WEB-INF/lib にデプロイしてしまうようで。一度手動で消したらそれ以降は追加しに行かないようなので、その対処で目をつぶることにした。