The Ja-Jakarta ProjectTomcat Servlet/JSP コンテナ

リンク

ユーザガイド

リファレンス

Tomcat開発

Tomcat5 サーブレット/JSP コンテナ

クラスローダの手引き

Printer Friendly Version
印刷用
バージョン
手始めに

アプリケーション開発担当および配備担当が、クラスやリソースのファイルを Webアプリケーションで使えるようにするためにどこに置くかという決定の 95% をカバーするルールは以下の通りです。

  • 個々の Webアプリケーション固有のクラスやリソースについては、 Webアプリケーションの配置箇所の /WEB-INF/classes にアーカイブせずに置くか、これらのクラスやリソースを含む JAR ファイルを Webアプリケーションの配置箇所の /WEB-INF/lib に置きます。
  • すべての Webアプリケーションを通して共有すべきクラスやリソースについては、 $CATALINA_HOME/shared/classes にアーカイブせずに置くか、 これらのクラスやリソースを含む JAR ファイルを $CATALINA_HOME/shared/lib に置きます。
概要

多くのサーバアプリケーション同様、Tomcat 5 も様々なクラスローダ (つまり java.lang.ClassLoader を実装したクラス) をインストールします。それは、コンテナの様々な部分やコンテナ上で動作する Webアプリケーションが、 利用可能なクラスやリソースの様々なリポジトリにアクセスできるようになるためです。 このメカニズムは、Servlet 仕様バージョン 2.4 で定義された機能 --特に9.4節と9.6節-- を提供するのに使われています。

Java 2 (つまり JDK 1.2 以降) 環境では、 クラスローダは親子関係のツリーとして構成されています。通常、 クラスローダが個々のクラスやリソースのロードの要求を受けると、 まずは要求を親のクラスローダに委譲し、 親のクラスローダ(複数の場合あり)が要求されたクラスやリソースを見つけられなかった場合だけ自分のリポジトリを見に行きます。 以下で説明するようにこれとは若干異なりますが、 Webアプリケーション用クラスローダのモデルも基本原則は同じです。

Tomcat 5 を起動すると、 以下のような親子関係に編成された一連のクラスローダを生成します。 以下の図では、親のクラスローダが子のクラスローダの上に表記されています。

      Bootstrap
         |
       System
         |
       Common
     /      \
 Catalina   Shared
            /   \
        Webapp1  Webapp2 ... 

これらのクラスローダのそれぞれの特徴については、 クラスローダが参照可能にするクラスやリソースの配置場所も含めて、 以下の節で詳細を説明します。

クラスローダ定義

上の図で示した通り Tomcat 5 は、 以下のクラスローダを初期化の際に生成します。

  • Bootstrap - このクラスローダには Java 仮想マシン (JVM) が提供する基本ランタイムクラスと、加えてシステム拡張ディレクトリ ($JAVA_HOME/jre/lib/ext) のすべてのクラスが含まれています。 注意 - JVM によっては2つ以上のクラスローダとして実装されている場合もありますし、 (クラスローダとして)まったく参照できない場合もあります。
  • System - このクラスローダは通常、CLASSPATH 環境変数の内容を元に初期化されます。こうしたクラスは Tomcat 内部クラスからも、 Webアプリケーションからも参照できます。しかし、標準の Tomcat 5 起動スクリプト ($CATALINA_HOME/bin/catalina.sh または %CATALINA_HOME%\bin\catalina.bat) では、 CLASSPATH 環境変数そのものの内容を完全に無視し、 代わりに以下のリポジトリから System クラスローダを構築します。
    • $CATALINA_HOME/bin/bootstrap.jar - Tomcat 5 サーバを初期化するのに使う main() メソッドと、 サーバが依存するクラスローダ実装クラスが含まれます。
    • $JAVA_HOME/lib/tools.jar - JSP ページを Servlet クラスに変換する "javac" コンパイラが入っています。
    • $CATALINA_HOME/bin/commons-logging-api.jar - Jakarta Commons Logging の API。
    • $CATALINA_HOME/bin/commons-daemon.jar - Jakarta Commons Daemon の API。
  • Common - このクラスローダには、Tomcat 内部クラスからも、 すべての Webアプリケーションからも参照可能になっている追加クラスが含まれます。 アプリケーションクラスは、 通常はここに置くべきではありません$CATALINA_HOME/common/classes にある アーカイブされていないクラスやリソースのすべて、それに $CATALINA_HOME/commons/endorsed$CATALINA_HOME/common/libにある JAR ファイル内のクラスやリソースのすべてをこのクラスローダから参照できます。 デフォルトでは以下のものが含まれます。
    • ant.jar - Apache Ant。
    • commons-collection.jar - Jakarta Commons Collection。
    • commons-dbcp.jar - Jakarta Commons DBCP。JDBC コネクションプールを Webアプリケーションに提供します。
    • commons-el.jar - Jakarta Commons EL。Jasper で使う EL (Expression Language) を実装します。
    • commons-pool.jar - Jakarta Commons Pool。
    • jasper-compiler.jar - JSP 2.0 コンパイラ
    • jasper-runtime.jar - JSP 2.0 ランタイム。
    • jmx.jar - JMX 1.2 実装。
    • jsp-api.jar - JSP 2.0 API。
    • naming-common.jar - Tomcat 5 で使われる JNDI 実装。 メモリ上のネーミングコンテキストに相当します。
    • naming-factory.jar - The JNDI Tomcat 5 で使われる JNDI 実装。 エンタープライズリソース (EJBやコネクションプール) への参照を解決します。
    • naming-resources.jar - 特殊な JNDI ネーミングコンテキスト実装。 Webアプリケーションの静的リソースに相当するものとして使われます。
    • servlet-api.jar - Servlet と JSP の API クラス。
    • xerces.jar - XML パーサ。Tomcat 内部クラスと Webアプリケーションから参照可能です。
  • Catalina - このクラスローダーは初期化時に、Tomcat 5 そのものを実装するのに必要なクラスやリソースすべてを含みます。 これらのクラスやリソースは Web アプリケーションからまったく参照できません。 $CATALINA_HOME/server/classes にあるアーカイブされないクラスやリソースすべて、 それに $CATALINA_HOME/server/lib にある JAR ファイル内のクラスやリソースがこのクラスローダで参照可能となります。 デフォルトでは以下のものが含まれます。
    • catalina.jar - Tomcat 5 の Catalina Servlet コンテナの部分の実装。
    • jakarta-regexp-X.Y.jar - 正規表現処理ライブラリである Jakarta Regexp のバイナリ配布。リクエストフィルタの実装で使われています。
    • servlets-xxxxx.jar - Tomcat の機能の一部として提供される内部 Servlet のそれぞれに関連するクラス。 対応するサービスが不要な場合に完全に削除できるように、 またセキュリティマネージャの特別な許可の対象にできるように、 これらは別々になっています。
    • tomcat-coyote.jar - Tomcat 5 の Coyote コネクタ。
    • tomcat-http11.jar - スタンドアロンの Java HTTP/1.1 コネクタ。
    • tomcat-jk2.jar - JK 2 Web サーバコネクタの Java の部分のクラス。 ApacheやiPlanet の iAS と iWSといった Web サーバの背後で Tomcat を実行できるようにします。
    • tomcat-util.jar - Tomcat コネクタの一部で必要なユーティリティクラス。
  • Shared - このクラスローダは、すべての Webアプリケーションを通して共有したいクラスやリソースを配置する場所です (Tomcat 内部クラスでもアクセスが必要な場合のみ例外で、 代わりに Common クラスローダに配置すべきです)。 $CATALINA_HOME/shared/classes 上のアーカイブされないクラスやリソースすべて、 それに $CATALINA_HOME/shared/lib にある JAR ファイル内のクラスやリソースがこのクラスローダで参照可能になります。 $CATALINA_BASE 環境変数を使って同じバイナリから複数の Tomcat インスタンスを実行する場合のこのクラスローダのリポジトリは、 $CATALINA_HOME ではなく $CATALINA_BASE を基準とします。
  • WebappX - 単一の Tomcat 5 インスタンスに配備された Webアプリケーションごとにクラスローダが1つずつ生成されます。 Webアプリケーションの配置場所の /WEB-INF/classes ディレクトリにあるアーカイブされないクラスやリソースすべて、 加えて Webアプリケーションの配置場所の /WEB-INF/lib にある JAR ファイル内のクラスやリソースは、これらを含んでいる Webアプリケーションから参照可能ですが、 他の Webアプリケーションからは参照できません。

上で説明した通り、Webアプリケーションクラスローダは、 デフォルトの Java 2 委譲モデルとは異なっています (これは Servlet 仕様バージョン 2.3 の 9.6 節での勧告に基づくものです)。Webアプリケーションの WebappX クラスローダからのクラスのロード要求が処理される際、 このクラスローダは最初に委譲を行なわずに、 ローカルのリポジトリをチェックします。ただし例外があり、 JRE の基本クラスに属するクラスはオーバーライドできません。(JDK 1.4 以降の XML パーサコンポーネントなど) いくつかのクラスについては、JDK 1.4 の Endorsed 機能が適用可能です (詳細については上の Common クラスローダ定義をご覧下さい)。それに加えて、以下のクラスパターンでは、 クラスローダは常に最初に委譲を行ないます (さらに親のクラスローダがロードしないクラスは自らロードを行ないます)。

  • javax.*
  • org.xml.sax.*
  • org.w3c.dom.*
  • org.apache.xerces.*
  • org.apache.xalan.*
最後に、Servlet API のクラスを含む JAR ファイルすべてをこのクラスローダは無視します。 Tomcat 5 の他のクラスローダはすべて通常の委譲パターンにしたがいます。

したがって、クラスやリソースのロードの際のリポジトリのチェックは、 Webアプリケーションから見ると以下の順序になります。

  • JVM のブートストラップクラス
  • System クラスローダの各クラス (上述)
  • Webアプリケーションの /WEB-INF/classes
  • Webアプリケーションの /WEB-INF/lib/*.jar
  • $CATALINA_HOME/common/classes
  • $CATALINA_HOME/common/endorsed/*.jar
  • $CATALINA_HOME/common/lib/*.jar
  • $CATALINA_HOME/shared/classes
  • $CATALINA_HOME/shared/lib/*.jar
XML パーサと JDK 1.4

JDK 1.4 リリースでは多くの変更がありましたが、その一環として、JAXP API と特定のバージョンの Xerces が JDK に同梱されるようになりました。これにより、 独自の XML パーサをアプリケーションで使いたい場合に影響が出ます。

Tomcat 5 以前のバージョンでは、$CATALINA_HOME/common/lib ディレクトリの XML パーサを置き換えるだけで、 すべての Webアプリケーションによって使われているパーサを変更できました。 しかしこのテクニックは、JDK 1.4 上で動かす場合には使えません。 なぜなら JDK 1.4 では、$CATALINA_HOME/common/lib よりも JDK 内の実装が通常のクラスローダの委譲過程において常に優先されるからです。

JDK 1.4 は、JCP (Java Community Process) 以外で定義された API (つまり W3C の DOM や SAX) の置き換えを可能にする "Endorsed Standards Override Mechanism" (推奨規格標準オーバーライド機構) をサポートしています。このメカニズムは XML パーサ実装の更新でも使えます。 詳細については、 http://java.sun.com/j2se/1.4/ja/docs/ja/guide/standards/index.html (原文) をご覧下さい。

Tomcat では、システムプロパティ設定として
-Djava.endorsed.dirs=$CATALINA_HOME/common/endorsed をコンテナを起動するコマンドラインに含めることによってこのメカニズムを使えます。 したがって、このディレクトリにインストールされたパーサを置き換えることができます。 この方法は JDK 1.4 のシステムでも有効です。


[訳注: この文書は高橋達男が翻訳し、 田中 ラ・マンチャ 良浩が校正しました。 日本語訳に対するコメントがあれば、report@jajakarta.orgに送って下さい。]
Copyright © 1999-2003, Apache Software Foundation