Jasper 2 JSPエンジン 使い方
目次
はじめに
Tomcat 11.0は、Jasper 2 JSPエンジンを使用して、Jakarta Pages 4.0仕様を実装しています。
Jasper 2は、元のJasperよりもパフォーマンスを大幅に向上させるために再設計されました。一般的なコードの改善に加えて、以下の変更が行われました。
- JSPカスタムタグのプーリング - JSPカスタムタグ用にインスタンス化されたJavaオブジェクトをプールして再利用できるようになりました。これにより、カスタムタグを使用するJSPページのパフォーマンスが大幅に向上します。
- バックグラウンドJSPコンパイル - すでにコンパイルされているJSPページを変更した場合、Jasper 2はそのページをバックグラウンドで再コンパイルできます。以前にコンパイルされたJSPページは、引き続きリクエストを処理できます。新しいページが正常にコンパイルされると、古いページに置き換えられます。これにより、本番サーバー上のJSPページの可用性が向上します。
- インクルードされたページの変更時にJSPを再コンパイル - Jasper 2は、JSPからコンパイル時にインクルードされたページが変更されたことを検出し、親JSPを再コンパイルできるようになりました。
- JDTを使用してJSPページをコンパイル - Eclipse JDT Javaコンパイラが、JSP Javaソースコードのコンパイルを実行するために使用されるようになりました。このコンパイラは、コンテナクラスローダーからソース依存関係をロードします。Antとjavacも引き続き使用できます。
Jasperは、サーブレットクラスorg.apache.jasper.servlet.JspServlet
を使用して実装されています。
設定
デフォルトでは、JasperはWebアプリケーションの開発を行う際に使用するように設定されています。本番Tomcatサーバーで使用するためにJasperを設定する方法については、本番環境の設定セクションを参照してください。
Jasperを実装するサーブレットは、グローバルの$CATALINA_BASE/conf/web.xml
の初期化パラメータを使用して設定されます。
- checkInterval - developmentがfalseで、checkIntervalがゼロより大きい場合、バックグラウンドコンパイルが有効になります。checkIntervalは、JSPページ(およびその依存ファイル)を再コンパイルする必要があるかどうかを確認する間隔(秒単位)です。デフォルトは
0
秒です。 - classdebuginfo - クラスファイルはデバッグ情報付きでコンパイルする必要がありますか?
true
またはfalse
、デフォルトはtrue
。 - classpath - 生成されたサーブレットをコンパイルするために使用されるクラスパスを定義します。このパラメータは、ServletContext属性org.apache.jasper.Constants.SERVLET_CLASSPATHが設定されていない場合にのみ有効です。この属性は、JasperがTomcat内で使用される場合は常に設定されます。デフォルトでは、クラスパスは現在のWebアプリケーションに基づいて動的に作成されます。
- compiler - JSPページのコンパイルにAntが使用するコンパイラを指定します。有効な値は、Antのjavacタスクのcompiler属性と同じです。値が設定されていない場合、Antを使用する代わりに、デフォルトのEclipse JDT Javaコンパイラが使用されます。デフォルト値はありません。この属性が設定されている場合は、
setenv.[sh|bat]
を使用して、ant.jar
、ant-launcher.jar
、およびtools.jar
をCLASSPATH
環境変数に追加する必要があります。 - compilerSourceVM - ソースファイルと互換性のあるJDKバージョンは何ですか? (デフォルト値:
17
) - compilerTargetVM - 生成されたファイルと互換性のあるJDKバージョンは何ですか? (デフォルト値:
17
) - development - Jasperは開発モードで使用されていますか? trueの場合、JSPが変更されているかどうかを確認する頻度は、modificationTestIntervalパラメータで指定できます。
true
またはfalse
、デフォルトはtrue
。 - displaySourceFragment - 例外メッセージにソースフラグメントを含める必要がありますか?
true
またはfalse
、デフォルトはtrue
。 - dumpSmap - JSR45デバッグ用のSMAP情報をファイルにダンプする必要がありますか?
true
またはfalse
、デフォルトはfalse
。suppressSmapがtrueの場合はfalse
。 - enablePooling - タグハンドラーのプーリングを有効にするかどうかを決定します。これはコンパイルオプションです。すでにコンパイルされているJSPの動作は変更されません。
true
またはfalse
、デフォルトはtrue
。 - engineOptionsClass - Jasperの構成に使用されるOptionsクラスを指定できます。存在しない場合は、デフォルトのEmbeddedServletOptionsが使用されます。
- errorOnUseBeanInvalidClassAttribute - useBeanアクションのclass属性の値が有効なBeanクラスではない場合に、Jasperはエラーを発行する必要がありますか?
true
またはfalse
、デフォルトはtrue
。 - fork - AntにJSPページのコンパイルをフォークさせて、Tomcatとは別のJVMで実行する必要がありますか?
true
またはfalse
、デフォルトはtrue
。 - genStringAsCharArray - 一部のケースでパフォーマンスを向上させるために、テキスト文字列を文字配列として生成する必要がありますか?デフォルトは
false
。 - javaEncoding - Javaソースファイルの生成に使用するJavaファイルのエンコード。デフォルトは
UTF8
。 - keepgenerated - 各ページの生成されたJavaソースコードを削除せずに保持する必要がありますか?
true
またはfalse
、デフォルトはtrue
。 - mappedfile - デバッグを容易にするために、入力行ごとに1つのprintステートメントを持つ静的コンテンツを生成する必要がありますか?
true
またはfalse
、デフォルトはtrue
。 - maxLoadedJsps - WebアプリケーションにロードされるJSPの最大数。この数を超えるJSPがロードされると、ロードされているJSPの数がこの制限を超えないように、最も最近使用されていないJSPがアンロードされます。ゼロ以下の値は、制限がないことを示します。デフォルトは
-1
- jspIdleTimeout - JSPがアンロードされるまでにアイドル状態にできる時間(秒単位)。ゼロ以下の値は、決してアンロードしないことを示します。デフォルトは
-1
- modificationTestInterval - JSP(およびその依存ファイル)が、最後に変更を確認した時点から指定された時間間隔(秒単位)の間、変更を確認されないようにします。値が0の場合、アクセスごとにJSPが確認されます。開発モードでのみ使用されます。デフォルトは
4
秒です。 - recompileOnFail - JSPのコンパイルが失敗した場合、modificationTestIntervalを無視して、次のアクセスで再コンパイルをトリガーする必要がありますか?開発モードでのみ使用され、コンパイルにコストがかかり、過度のリソース使用につながる可能性があるため、デフォルトでは無効になっています。
- scratchdir - JSPページのコンパイル時に使用するスクラッチディレクトリは何ですか?デフォルトは、現在のWebアプリケーションの作業ディレクトリです。
- suppressSmap - JSR45デバッグ用のSMAP情報の生成を抑制する必要がありますか?
true
またはfalse
、デフォルトはfalse
。 - trimSpaces - 空白文字のみで構成されるテンプレートテキストを、出力から削除する (
true
)、単一のスペースに置き換える (single
)、または変更しない (false
) のどれにする必要がありますか? または、extended
オプションを使用すると、テンプレートテキストの先頭と末尾の空白文字が削除され、テンプレートテキスト内の連続する空白文字と改行が単一の改行に折りたたまれます。 JSP ページまたはタグファイルでtrimDirectiveWhitespaces
の値をtrue
に指定した場合、そのページ/タグではこの設定よりも優先されることに注意してください。 デフォルトはfalse
です。 - xpoweredBy - 生成されたサーブレットによってX-Powered-Byレスポンスヘッダーが追加されるかどうかを決定します。
true
またはfalse
、デフォルトはfalse
。 - strictQuoteEscaping - スクリプトレット式が属性値に使用されている場合、引用符のエスケープに関するJSP.1.6のルールを厳密に適用する必要がありますか?
true
またはfalse
、デフォルトはtrue
。 - quoteAttributeEL - ELがJSPページの属性値で使用されている場合、JSP.1.6で説明されている属性の引用符付けのルールを式に適用する必要がありますか?
true
またはfalse
、デフォルトはtrue
。 - variableForExpressionFactory - 式言語の式ファクトリに使用する変数の名前。指定しない場合、デフォルト値の
_el_expressionfactory
が使用されます。 - variableForInstanceManager - インスタンスマネージャーファクトリに使用する変数の名前。指定しない場合、デフォルト値の
_jsp_instancemanager
が使用されます。 - poolTagsWithExtends - デフォルトでは、pageディレクティブのextends属性を介して独自のベースクラスを使用するJSPは、必要な初期化が行われたことをJasperが保証できないため、タグのプーリングが無効になります。これにより、パフォーマンスに悪影響を与える可能性があります。代替のベースクラスがServlet.init()から_jspInit()を呼び出す場合、このプロパティを
true
に設定すると、代替のベースクラスでのプーリングが有効になります。代替のベースクラスが_jspInit()を呼び出さず、このプロパティがtrue
の場合、タグを使用しようとするとNPEが発生します。true
またはfalse
、デフォルトはfalse
。 - strictGetProperty -
true
の場合、jsp:getProperty
アクションで参照されるオブジェクトが、JSP 2.0以降の仕様のJSP.5.3章で指定されているように、事前にJSPプロセッサに「導入」されていることが要求されます。true
またはfalse
、デフォルトはtrue
。 - strictWhitespace -
false
の場合、属性名の前の空白文字の要件が緩和され、空白文字がないことがエラーの原因にはなりません。true
またはfalse
、デフォルトはtrue
。 - jspServletBase - JSPから生成されたサーブレットのベースクラス。指定しない場合、デフォルト値の
org.apache.jasper.runtime.HttpJspBase
が使用されます。 - serviceMethodName - ベースクラスによって呼び出されるサービスメソッドの名前。指定しない場合、デフォルト値の
_jspService
が使用されます。 - servletClasspathAttribute - JSPのクラスパスを提供するServletContext属性の名前。指定しない場合、デフォルト値の
org.apache.catalina.jsp_classpath
が使用されます。 - jspPrecompilationQueryParameter - JSPエンジンにサーブレットを事前生成するだけで、呼び出さないようにするクエリパラメータの名前。指定しない場合、JSP仕様(JSP.11.4.2)で定義されているデフォルト値の
jsp_precompile
が使用されます。 - generatedJspPackageName - コンパイルされたJSPのデフォルトパッケージ名。指定しない場合、デフォルト値の
org.apache.jsp
が使用されます。 - generatedTagFilePackageName - タグファイルから生成されたタグハンドラーのデフォルトパッケージ名。指定しない場合、デフォルト値の
org.apache.jsp.tag
が使用されます。 - tempVariableNamePrefix - 生成された一時変数名に使用するプレフィックス。指定しない場合、デフォルト値の
_jspx_temp
が使用されます。 - useInstanceManagerForTags -
true
の場合、インスタンスマネージャーはタグハンドラーインスタンスを取得するために使用されます。true
またはfalse
、デフォルトはfalse
。 - limitBodyContentBuffer -
true
の場合、bodyContentTagBufferSize
初期化パラメータの値を超えて拡張するタグバッファーは破棄され、新しいバッファーが作成されます。true
またはfalse
、デフォルトはfalse
。 - bodyContentTagBufferSize - タグバッファーを作成するときに使用するサイズ(文字数)。指定しない場合、デフォルト値の
org.apache.jasper.Constants.DEFAULT_TAG_BUFFER_SIZE
(512)が使用されます。
Eclipse JDTからのJavaコンパイラは、デフォルトのコンパイラとして含まれています。これは高度なJavaコンパイラであり、Tomcatクラスローダーからすべての依存関係をロードします。これにより、数十のJARがある大規模なインストールでコンパイルするときに非常に役立ちます。高速なサーバーでは、これにより、大規模なJSPページでも1秒未満の再コンパイルサイクルが可能になります。
以前のTomcatリリースで使用されていたApache Antは、上記のコンパイラ属性を構成することにより、新しいコンパイラの代わりに使用できます。
アプリケーションのJSPサーブレットの設定を変更する必要がある場合は、/WEB-INF/web.xml
でJSPサーブレットを再定義して、デフォルト構成をオーバーライドできます。ただし、JSPサーブレットクラスが認識されない可能性があるため、別のコンテナにアプリケーションをデプロイしようとすると、問題が発生する可能性があります。この問題を回避するには、Tomcat固有の/WEB-INF/tomcat-web.xml
デプロイメント記述子を使用します。形式は/WEB-INF/web.xml
と同じです。デフォルト設定はオーバーライドされますが、/WEB-INF/web.xml
の設定はオーバーライドされません。Tomcat固有であるため、アプリケーションがTomcatにデプロイされた場合にのみ処理されます。
既知の問題
バグ39089で説明されているように、既知のJVMの問題であるバグ6294277により、非常に大規模なJSPをコンパイルするときにjava.lang.InternalError: name is too long to represent
例外が発生する場合があります。これが観察された場合は、次のいずれかを使用することで回避できます。
- JSPのサイズを縮小する
suppressSmap
をtrue
に設定して、SMAPの生成とJSR-045のサポートを無効にする。
本番環境の設定
実行できる主なJSPの最適化は、JSPの事前コンパイルです。ただし、jsp-property-group機能を使用している場合など、これが不可能または実用的でない場合は、Jasperサーブレットの構成が重要になります。
本番TomcatサーバーでJasper 2を使用する場合は、デフォルト構成から次の変更を行うことを検討する必要があります。
- development - JSPページのコンパイルへのアクセスチェックを無効にするには、これを
false
に設定します。 - genStringAsCharArray - わずかに効率的な文字配列を生成するには、これを
true
に設定します。 - modificationTestInterval - JSPの動的な生成など、何らかの理由でdevelopmentを
true
に設定する必要がある場合は、これを高い値に設定すると、パフォーマンスが大幅に向上します。 - trimSpaces - レスポンスから不要なバイトを削除するには、これを
single
またはextended
に設定することを検討してください。
Webアプリケーションのコンパイル
JSPCを使用したWebアプリケーションのコンパイルには、Antを使用することをお勧めします。 JSPsを事前にコンパイルする場合、suppressSmapがfalseで、compileがtrueの場合にのみ、SMAP情報が最終クラスに含まれることに注意してください。 次に示すスクリプト(同様のスクリプトは「deployer」ダウンロードに含まれています)を使用して、webappを事前にコンパイルします
<project name="Webapp Precompilation" default="all" basedir=".">
<import file="${tomcat.home}/bin/catalina-tasks.xml"/>
<target name="jspc">
<jasper
validateXml="false"
uriroot="${webapp.path}"
webXmlInclude="${webapp.path}/WEB-INF/generated_web.xml"
outputDir="${webapp.path}/WEB-INF/src" />
</target>
<target name="compile">
<mkdir dir="${webapp.path}/WEB-INF/classes"/>
<mkdir dir="${webapp.path}/WEB-INF/lib"/>
<javac destdir="${webapp.path}/WEB-INF/classes"
debug="on" failonerror="false"
srcdir="${webapp.path}/WEB-INF/src"
excludes="**/*.smap">
<classpath>
<pathelement location="${webapp.path}/WEB-INF/classes"/>
<fileset dir="${webapp.path}/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
<pathelement location="${tomcat.home}/lib"/>
<fileset dir="${tomcat.home}/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${tomcat.home}/bin">
<include name="*.jar"/>
</fileset>
</classpath>
<include name="**" />
<exclude name="tags/**" />
</javac>
</target>
<target name="all" depends="jspc,compile">
</target>
<target name="cleanup">
<delete>
<fileset dir="${webapp.path}/WEB-INF/src"/>
<fileset dir="${webapp.path}/WEB-INF/classes/org/apache/jsp"/>
</delete>
</target>
</project>
次のコマンドラインを使用してスクリプトを実行できます(トークンをTomcatベースパスと、事前にコンパイルする必要があるwebappへのパスに置き換えます)
$ANT_HOME/bin/ant -Dtomcat.home=<$TOMCAT_HOME> -Dwebapp.path=<$WEBAPP_PATH>
次に、事前コンパイル中に生成されたサーブレットの宣言とマッピングを、Webアプリケーションのデプロイメント記述子に追加する必要があります。 ${webapp.path}/WEB-INF/generated_web.xml
を${webapp.path}/WEB-INF/web.xml
ファイルの適切な場所に挿入します。(マネージャーを使用して)Webアプリケーションを再起動し、事前コンパイルされたサーブレットで正常に実行されていることを確認するためにテストします。 Webアプリケーションのデプロイメント記述子に配置された適切なトークンを使用して、Antフィルタリング機能を使用して生成されたサーブレットの宣言とマッピングを自動的に挿入することもできます。 これは、Tomcatで配布されるすべてのWebappがビルドプロセスの一部として自動的にコンパイルされる方法です。
jasperタスクでは、addWebXmlMappings
オプションを使用して、${webapp.path}/WEB-INF/generated_web.xml
を現在のWebアプリケーションのデプロイメント記述子と${webapp.path}/WEB-INF/web.xml
で自動的にマージできます。
JSPに特定のバージョンのJavaを使用する場合は、javacコンパイラタスク属性source
およびtarget
を適切な値で追加します。 たとえば、Java 16用にJSPをコンパイルするには16
です。
本番環境では、debug="off"
を使用してデバッグ情報を無効にすることをお勧めします。
最初のJSP構文エラーでJSPの生成を停止したくない場合は、failOnError="false"
を使用し、showSuccess="true"
を使用すると、すべての成功したJSP to Javaの生成が出力されます。 ${webapp.path}/WEB-INF/src
で生成されたjavaソースファイルをクリーンアップし、${webapp.path}/WEB-INF/classes/org/apache/jsp
でJSPサーブレットクラスをコンパイルすると非常に役立つ場合があります。
ヒント
- 別のTomcatリリースに切り替える場合は、新しいTomcatバージョンでJSPを再生成して再コンパイルします。
- Servletコンテキストパラメーターを使用してPageContextプーリング
org.apache.jasper.runtime.JspFactoryImpl.POOL_SIZE=-1
を無効にし、JSPサーブレット初期化パラメーターlimitBodyContentBuffer=true
でバッファリングを制限します。 デフォルトからの変更はパフォーマンスに影響を与える可能性がありますが、アプリケーションによって異なることに注意してください。
最適化
Jasperには、ユーザーが環境に合わせて動作を最適化できる拡張ポイントが多数用意されています。
これらの拡張ポイントの1つは、タグプラグインメカニズムです。 これにより、Webアプリケーションが使用するタグハンドラーの代替実装を提供できます。 タグプラグインは、WEB-INF
にあるtagPlugins.xml
ファイルを介して登録されます。 JSTLのサンプルプラグインがJasperに含まれています。
2番目の拡張ポイントは、Expression Languageインタープリターです。 代替インタープリターは、ServletContext
を通じて構成できます。 代替ELインタープリターの構成方法の詳細については、ELInterpreterFactory
javadocを参照してください。 タグ設定を主にターゲットとする代替インタープリターは、org.apache.jasper.optimizations.ELInterpreterTagSetters
で提供されます。 最適化と仕様コンプライアンスへの影響の詳細については、javadocを参照してください。
String値をEnumに強制変換するための拡張ポイントも提供されています。 これはorg.apache.jasper.optimizations.StringInterpreterEnum
で提供されています。 最適化と仕様コンプライアンスへの影響の詳細については、javadocを参照してください。