LoginSignup
10
10

More than 5 years have passed since last update.

Tomcat で巨大なJSPファイルをなんとかコンパイルする方法

Posted at

サイズの大きい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 limit

Stacktrace:
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 の設定を加えます。

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>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>

という設定が web.xml の前半部分にありますので…

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 は動きます。
超巨大なファイルであればダメかもしれませんが、未検証です。

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10