サイズの大きいJSPがあると、Tomcatで実行時エラーが発生します
An error occurred at line: [264] in the generated java file: [D:\apache-tomcat-7.0.54\work\SampleApp\org\apache\jsp\WEB_002dINF\jsp\Sample01_jsp.java]
The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes limitStacktrace:
at org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:103)
at org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:366)
このような感じで、JSP をコンパイルしようとするタイミングでエラーが発生します。
今回は 200KB くらいの JSP ファイルで発生しました。
Tomcat が JSP を Java ファイルに変換するのですが、その Java ファイルのサイズが 65,535 byte を超えるとエラーが発生する仕様となっているようです。
解決策① JSP をファイル分割する
<jsp:include> などを使って、JSP を分割することで、JSP から変換した Java ファイルひとつひとつのファイルサイズを抑えることができます。
確実な手段ですが、一度作りあげた巨大な JSP ファイルを分割していくのはかなり一苦労です。
解決策② Tomcat JSP Engine の mappedfile 設定を変える
Tomcat は JSP の仕様を実装するために、Jasper 2 JSP Engine というものを使用しています。
そして、この JSP Engine には mappedfile という設定があります。
この mappedfile 設定を有効にすると JSP から Java に変換する際、
デバッグしやすくなるように JSP 1行に対して、Java 1行が対応するように変換します。
逆にこの設定を無効にすると、余計なことを気にせず Java に変換します。
つまり、Java ファイルのファイルサイズが小さくなります。
mappedfile 設定を変更する方法
/conf/web.xml の内容を変更します。
JspServlet について設定している箇所に mappedfile の設定を加えます。
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
という設定が web.xml の前半部分にありますので…
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>mappedfile</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
という感じに mappedfile のパラメータに対して false を設定します。
何も設定しなければ、mappedfile は true(有効:JSP 1行に Java 1行)がデフォルトです。
Tomcat のバージョンによってはデフォルトが false になっていたものもあるようです。
注意点
デフォルト設定よりも Java ファイルを比較的小さくする回避策ですので、
超巨大な JSP であれば、この回避策を施したとしても 65,535 byte の上限を超えてしまう可能性があります。
ちなみに
Tomcat(≒Jasper 2 JSP Engine)固有のエラーのようです。
WebSphere Application Server(WAS)だと、同様の実行時エラーは発生しませんでした。
同じ JSP でも WAS は動きます。
超巨大なファイルであればダメかもしれませんが、未検証です。