JNDI リソースの使い方
目次
はじめに
Tomcat は、その下で実行されている各 Web アプリケーションに対して、Jakarta EE アプリケーションサーバーが提供するものと互換性のある方法で、JNDI InitialContext 実装インスタンスを提供します。Jakarta EE 標準は、リソースを参照/定義するための標準的な要素セットを /WEB-INF/web.xml
ファイルに提供します。
JNDI のプログラミング API と、Tomcat が提供するサービスをエミュレートする Jakarta EE サーバーでサポートされる機能の詳細については、以下の仕様を参照してください。
- Java Naming and Directory Interface (JDK 1.4 以降に含まれています)
- Jakarta EE プラットフォーム仕様 (特に、ネーミングに関する第5章を参照)
web.xml 設定
Web アプリケーションのリソースを定義するために、Web アプリケーションのデプロイメント記述子(/WEB-INF/web.xml
)で以下の要素を使用できます。
<env-entry>
- 環境エントリ。アプリケーションの動作方法を設定するために使用できる単一値パラメータです。<resource-ref>
- リソース参照。通常は、JDBCDataSource
、Jakarta MailSession
、Tomcat に設定されたカスタムオブジェクトファクトリなどのリソースのオブジェクトファクトリへの参照です。<resource-env-ref>
- リソース環境参照。Servlet 2.4 で追加されたresource-ref
の新しいバリエーションで、認証情報を必要としないリソースの設定がより簡単になっています。
Tomcat がリソースの作成に使用する適切なリソースファクトリを特定でき、それ以上の設定情報が必要ない場合は、Tomcat は /WEB-INF/web.xml
の情報を使用してリソースを作成します。
Tomcat は、web.xml では指定できない JNDI リソース向けの Tomcat 固有のオプションをいくつか提供しています。これらには、Web アプリケーションの停止時に JNDI リソースのより迅速なクリーンアップを可能にする closeMethod
と、すべての JNDI ルックアップに対してリソースの新しいインスタンスを作成するかどうかを制御する singleton
が含まれます。これらの設定オプションを使用するには、リソースを Web アプリケーションの <Context>
要素、または $CATALINA_BASE/conf/server.xml
の <GlobalNamingResources>
要素で指定する必要があります。
context.xml 設定
Tomcat が適切なリソースファクトリを特定できない場合、または追加の設定情報が必要な場合は、Tomcat がリソースを作成する前に、Tomcat 固有の追加設定を指定する必要があります。Tomcat 固有のリソース設定は、$CATALINA_BASE/conf/server.xml
または、できれば Web アプリケーションごとのコンテキスト XML ファイル(META-INF/context.xml
)で指定できる <Context>
要素に入力します。
Tomcat 固有のリソース設定は、<Context>
要素内の以下の要素を使用して行われます。
- <Environment> - JNDI
InitialContext
を介して Web アプリケーションに公開されるスカラー環境エントリの値を設定します(Web アプリケーションのデプロイメント記述子に<env-entry>
要素を含めることと同じです)。 - <Resource> - アプリケーションが利用できるリソースの名前とデータ型を設定します(Web アプリケーションのデプロイメント記述子に
<resource-ref>
要素を含めることと同じです)。 - <ResourceLink> - グローバル JNDI コンテキストで定義されたリソースへのリンクを追加します。リソースリンクを使用して、Web アプリケーションに <Server> 要素の <GlobalNamingResources> 子要素で定義されたリソースへのアクセスを許可します。
- <Transaction> -
java:comp/UserTransaction
で利用可能な UserTransaction オブジェクトインスタンスをインスタンス化するためのリソースファクトリを追加します。
これらの要素は、<Context>
要素内にいくつでもネストでき、その特定の Web アプリケーションのみに関連付けられます。
リソースが <Context>
要素で定義されている場合、そのリソースを /WEB-INF/web.xml
で定義する必要はありません。ただし、Web アプリケーションのリソース要件を文書化するために、/WEB-INF/web.xml
にエントリを保持することをお勧めします。
Web アプリケーションのデプロイメント記述子(/WEB-INF/web.xml
)に含まれる <env-entry>
要素と、Web アプリケーションの <Context>
要素の一部である <Environment>
要素で同じリソース名が定義されている場合、対応する <Environment>
要素で許可されている場合(override
属性を "true" に設定することにより)**のみ**、デプロイメント記述子の値が優先されます。
グローバル設定
Tomcat は、サーバー全体でグローバルリソースの個別の名前空間を保持します。これらは、$CATALINA_BASE/conf/server.xml
の <GlobalNamingResources>
要素で設定されます。<ResourceLink> を使用して Web アプリケーションごとのコンテキストに含めることで、これらのリソースを Web アプリケーションに公開できます。
リソースが <ResourceLink> を使用して定義されている場合、そのリソースを /WEB-INF/web.xml
で定義する必要はありません。ただし、Web アプリケーションのリソース要件を文書化するために、/WEB-INF/web.xml
にエントリを保持することをお勧めします。
リソースの使用
InitialContext
は、Web アプリケーションの初期デプロイ時に設定され、Web アプリケーションコンポーネント(読み取り専用アクセス用)が利用できるようになります。設定されたすべてのエントリとリソースは、JNDI 名前空間の java:comp/env
部分に配置されるため、リソース(この場合は JDBC DataSource
)への一般的なアクセスは次のようになります。
// Obtain our environment naming context
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
// Look up our data source
DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");
// Allocate and use a connection from the pool
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
Tomcat 標準リソースファクトリ
Tomcat には、Web アプリケーションにサービスを提供できる一連の標準リソースファクトリが含まれていますが、Web アプリケーションまたはデプロイメント記述子を修正することなく、設定の柔軟性(<Context>
要素を介して)を提供します。以下の各サブセクションでは、標準リソースファクトリの構成と使用方法について詳しく説明します。
Tomcat で独自のカスタムリソースファクトリクラスを作成、インストール、設定、および使用する方法については、カスタムリソースファクトリの追加 を参照してください。
注 - 標準リソースファクトリのうち、「JDBC データソース」と「ユーザートランザクション」ファクトリのみが他のプラットフォームで利用可能であることが義務付けられており、プラットフォームが Jakarta EE 仕様を実装している場合にのみ必要です。その他のすべての標準リソースファクトリ、および自分で記述したカスタムリソースファクトリは Tomcat 固有であり、他のコンテナで利用できるとは想定できません。
汎用 JavaBean リソース
0. はじめに
このリソースファクトリは、標準の JavaBeans ネーミング規則(つまり、引数のないコンストラクタを持ち、setFoo() ネーミングパターンに準拠したプロパティセッターを持つ)に準拠する*任意*の Java クラスのオブジェクトを作成するために使用できます。リソースファクトリは、ファクトリの singleton
属性が false
に設定されている場合にのみ、このエントリの lookup()
が行われるたびに、適切な Bean クラスの新しいインスタンスを作成します。
この機能を使用するために必要な手順を以下に示します。
1. JavaBean クラスを作成する
リソースファクトリがルックアップされるたびにインスタンス化される JavaBean クラスを作成します。この例では、次のようなクラス com.mycompany.MyBean
を作成するとします。
package com.mycompany;
public class MyBean {
private String foo = "Default Foo";
public String getFoo() {
return (this.foo);
}
public void setFoo(String foo) {
this.foo = foo;
}
private int bar = 0;
public int getBar() {
return (this.bar);
}
public void setBar(int bar) {
this.bar = bar;
}
}
2. リソース要件を宣言する
次に、Web アプリケーションのデプロイメント記述子(/WEB-INF/web.xml
)を変更して、この Bean の新しいインスタンスを要求する JNDI 名を宣言します。最も簡単な方法は、次のように <resource-env-ref>
要素を使用することです。
<resource-env-ref>
<description>
Object factory for MyBean instances.
</description>
<resource-env-ref-name>
bean/MyBeanFactory
</resource-env-ref-name>
<resource-env-ref-type>
com.mycompany.MyBean
</resource-env-ref-type>
</resource-env-ref>
警告 - Web アプリケーションのデプロイメント記述子の DTD で必要な要素の順序を必ず守ってください! 詳細については、サーブレット仕様 を参照してください。
3. このリソースを使用するアプリケーションのコードを作成する
このリソース環境参照の一般的な使用例は次のとおりです。
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
writer.println("foo = " + bean.getFoo() + ", bar = " +
bean.getBar());
4. Tomcat のリソースファクトリを設定する
Tomcat のリソースファクトリを設定するには、この Web アプリケーションの <Context>
要素に次のような要素を追加します。
<Context ...>
...
<Resource name="bean/MyBeanFactory" auth="Container"
type="com.mycompany.MyBean"
factory="org.apache.naming.factory.BeanFactory"
bar="23"/>
...
</Context>
リソース名(ここでは bean/MyBeanFactory
)は、Web アプリケーションのデプロイメント記述子で指定された値と一致する必要があることに注意してください。また、bar
プロパティの値を初期化しています。これにより、新しい Bean が返される前に setBar(23)
が呼び出されます。 foo
プロパティは初期化していないため(初期化することもできます)、Bean にはコンストラクタによって設定されたデフォルト値が格納されます。
Bean プロパティの型が String
の場合、BeanFactory は指定されたプロパティ値を使用してプロパティセッターを呼び出します。Bean プロパティの型がプリミティブまたはプリミティブラッパーの場合、BeanFactory は値を適切なプリミティブまたはプリミティブラッパーに変換し、セッターを呼び出すときにその値を使用します。一部の Bean には、String
から自動的に変換できない型のプロパティがあります。Bean が String
を受け取る同じ名前の代替セッターを提供している場合、BeanFactory はそのセッターを使用しようとします。BeanFactory が値を使用できない、または適切な変換を実行できない場合、プロパティの設定は NamingException で失敗します。
以前の Tomcat リリースで利用可能だった forceString
プロパティは、セキュリティ強化策として削除されました。
メモリ UserDatabase リソース
0. はじめに
UserDatabase リソースは、通常、UserDatabase レルムで使用するためにグローバルリソースとして設定されます。Tomcat には、XML ファイル(通常は tomcat-users.xml
)によってサポートされる UserDatabase リソースを作成する UserDatabaseFactory が含まれています。
グローバル UserDatabase リソースを設定するために必要な手順を以下に示します。
1. XML ファイルを作成/編集する
XML ファイルは通常 $CATALINA_BASE/conf/tomcat-users.xml
にありますが、ファイルシステムのどこにでも配置できます。XML ファイルは $CATALINA_BASE/conf
に配置することをお勧めします。一般的な XML は次のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users>
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="tomcat" roles="tomcat"/>
<user username="both" password="tomcat" roles="tomcat,role1"/>
<user username="role1" password="tomcat" roles="role1"/>
</tomcat-users>
2. リソースを宣言する
次に、$CATALINA_BASE/conf/server.xml
を変更して、XML ファイルに基づいて UserDatabase リソースを作成します。次のようになります。
<Resource name="UserDatabase"
auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"
readonly="false" />
pathname
属性は、URL、絶対パス、または相対パスにすることができます。相対パスの場合、$CATALINA_BASE
に相対します。
readonly
属性はオプションであり、指定しない場合はデフォルトで true
になります。XML が書き込み可能な場合、Tomcat の起動時に書き込まれます。警告: ファイルが書き込まれる際、Tomcat を実行しているユーザーのデフォルトのファイル権限が継承されます。インストールのセキュリティを維持するために、これらの権限が適切であることを確認してください。
Realm で参照される場合、UserDatabase はデフォルトで pathname
の変更を監視し、最終変更時刻に変更が observed された場合にファイルをリロードします。これは、watchSource
属性を false
に設定することで無効にできます。
3. Realm の設定
Realm 設定ドキュメントに記載されているように、このリソースを使用するように UserDatabase Realm を設定します。
DataSource UserDatabase リソース
0. はじめに
Tomcat には、バックエンドとして DataSource
リソースを使用する UserDatabase
も含まれています。バックエンドリソースは、それを使用するユーザーデータベースと同じ JNDI コンテキストで宣言する必要があります。
グローバル UserDatabase リソースを設定するために必要な手順を以下に示します。
1. データベーススキーマ
ユーザーデータベースのデータベーススキーマは柔軟です。ユーザー(ユーザー名、パスワード)のテーブルと、各ユーザーに関連付けられたロールを一覧表示するもう1つのテーブルのみを使用して、DataSourceRealm
に使用されるスキーマと同じにすることができます。完全な UserDatabase
機能をサポートするには、グループの追加テーブルを含める必要があり、ユーザー、グループ、およびロール間の参照整合性と互換性があります。
グループと参照整合性を備えたフル機能のスキーマは次のとおりです。
create table users (
user_name varchar(32) not null primary key,
user_pass varchar(64) not null,
user_fullname varchar(128)
-- Add more attributes as needed
);
create table roles (
role_name varchar(32) not null primary key,
role_description varchar(128)
);
create table groups (
group_name varchar(32) not null primary key,
group_description varchar(128)
);
create table user_roles (
user_name varchar(32) references users(user_name),
role_name varchar(32) references roles(role_name),
primary key (user_name, role_name)
);
create table user_groups (
user_name varchar(32) references users(user_name),
group_name varchar(32) references groups(group_name),
primary key (user_name, group_name)
);
create table group_roles (
group_name varchar(32) references groups(group_name),
role_name varchar(32) references roles(role_name),
primary key (group_name, role_name)
);
グループを使用できない最小限のスキーマは次のとおりです(DataSourceRealm
と同じです)。
create table users (
user_name varchar(32) not null primary key,
user_pass varchar(64) not null,
-- Add more attributes as needed
);
create table user_roles (
user_name varchar(32),
role_name varchar(32),
primary key (user_name, role_name)
);
2. リソースを宣言する
次に、$CATALINA_BASE/conf/server.xml
を変更して、DataSource
とそのスキーマに基づいて UserDatabase リソースを作成します。次のようになります。
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.DataSourceUserDatabaseFactory"
dataSourceName="jdbc/authority" readonly="false"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"
roleTable="roles" groupTable="groups" userGroupTable="user_groups"
groupRoleTable="group_roles" groupNameCol="group_name" />
dataSourceName
属性は、UserDatabase
のバックエンドとなる DataSource
の JNDI 名です。 UserDatabase
と同じ JNDI Context
で宣言する必要があります。詳細な手順については、DataSource
リソースのドキュメントを参照してください。
readonly
属性はオプションであり、指定しない場合はデフォルトで true
になります。データベースが書き込み可能な場合、Tomcat 管理を介して UserDatabase
に加えられた変更は、save
操作を使用してデータベースに永続化できます。
あるいは、バックエンドデータベースに直接変更を加えることもできます。
3. リソースの設定
属性 | 説明 |
---|---|
dataSourceName |
この UserDatabase の JNDI JDBC DataSource の名前。 |
groupNameCol |
「グループ」、「グループロール」、および「ユーザーグループ」テーブルで、グループの名前を含む列の名前。 |
groupRoleTable |
|
groupTable |
|
readonly |
これが |
roleAndGroupDescriptionCol |
「ロール」テーブルと「グループ」テーブルで、ロールとグループの説明を含む列の名前。 |
roleNameCol |
「ロール」、「ユーザーロール」、および「グループロール」テーブルで、対応するユーザーに割り当てられたロール名を含む列の名前。 この属性は、ほとんどの設定で必須です。省略できるまれなケースについては、関連するレルムの allRolesMode 属性を参照してください。 |
roleTable |
|
userCredCol |
「ユーザー」テーブルで、ユーザーの資格情報(つまりパスワード)を含む列の名前。 |
userGroupTable |
|
userNameCol |
「ユーザー」、「ユーザーグループ」、および「ユーザーロール」テーブルで、ユーザーのユーザー名を含む列の名前。 |
userFullNameCol |
「ユーザー」テーブルで、ユーザーのフルネームを含む列の名前。 |
userRoleTable |
この属性は、ほとんどの設定で必須です。省略できるまれなケースについては、関連するレルムの allRolesMode 属性を参照してください。 |
userTable |
|
4. Realm の設定
Realm 設定ドキュメントに記載されているように、このリソースを使用するように UserDatabase Realm を設定します。
Jakarta Mail セッション
0. はじめに
多くの Web アプリケーションでは、電子メールメッセージの送信はシステムの機能に必要な部分です。Jakarta Mail API は、このプロセスを比較的簡単に行いますが、クライアントアプリケーションが認識している必要がある多くの構成の詳細(メッセージ送信に使用する SMTP ホストの名前を含む)が必要です。
Tomcat には、SMTP サーバーに接続するように既に設定されている、jakarta.mail.Session
セッションインスタンスを作成する標準リソースファクトリが含まれています。このようにして、アプリケーションはメールサーバーの設定環境の変更から完全に隔離されます。必要なときに、事前に設定されたセッションを要求して受信するだけです。
必要な手順の概要を以下に示します。
1. リソース要件の宣言
最初に行う必要があるのは、Web アプリケーションのデプロイメント記述子(/WEB-INF/web.xml
)を変更して、事前に設定されたセッションを検索する JNDI 名を宣言することです。慣例により、そのようなすべての名前は、すべての提供されたリソースファクトリのルートである標準の java:comp/env
ネーミングコンテキストを基準とした mail
サブコンテキストに解決される必要があります。典型的な web.xml
エントリは次のようになります。
<resource-ref>
<description>
Resource reference to a factory for jakarta.mail.Session
instances that may be used for sending electronic mail
messages, preconfigured to connect to the appropriate
SMTP server.
</description>
<res-ref-name>
mail/Session
</res-ref-name>
<res-type>
jakarta.mail.Session
</res-type>
<res-auth>
Container
</res-auth>
</resource-ref>
警告 - Web アプリケーションのデプロイメント記述子の DTD で必要な要素の順序を必ず守ってください! 詳細については、サーブレット仕様 を参照してください。
2. このリソースのアプリケーションの使用のコーディング
このリソース参照の一般的な使用法は次のようになります。
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
Session session = (Session) envCtx.lookup("mail/Session");
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(request.getParameter("from")));
InternetAddress to[] = new InternetAddress[1];
to[0] = new InternetAddress(request.getParameter("to"));
message.setRecipients(Message.RecipientType.TO, to);
message.setSubject(request.getParameter("subject"));
message.setContent(request.getParameter("content"), "text/plain");
Transport.send(message);
アプリケーションは、Web アプリケーションのデプロイメント記述子で宣言されたのと同じリソース参照名を使用していることに注意してください。これは、以下で説明するように、Web アプリケーションの <Context>
要素で設定されているリソースファクトリと照合されます。
3. Tomcat のリソースファクトリの構成
Tomcat のリソースファクトリを設定するには、この Web アプリケーションの <Context>
要素に次のような要素を追加します。
<Context ...>
...
<Resource name="mail/Session" auth="Container"
type="jakarta.mail.Session"
mail.smtp.host="localhost"/>
...
</Context>
リソース名(ここでは mail/Session
)は、Web アプリケーションのデプロイメント記述子で指定された値と一致する必要があることに注意してください。 mail.smtp.host
パラメーターの値をカスタマイズして、ネットワークに SMTP サービスを提供するサーバーを指すようにします。
追加のリソース属性と値は、プロパティと値に変換され、java.util.Properties
コレクションの一部として jakarta.mail.Session.getInstance(java.util.Properties)
に渡されます。Jakarta Mail 仕様の付録 A で定義されているプロパティに加えて、個々のプロバイダーは追加のプロパティもサポートする場合があります。
リソースが password
属性と mail.smtp.user
属性または mail.user
属性のいずれかで構成されている場合、Tomcat のリソースファクトリは jakarta.mail.Authenticator
を構成してメールセッションに追加します。
4. Jakarta Mail API のインストール
配布パッケージを解凍し、jakarta.mail-api-2.1.0.jar を $CATALINA_HOME/lib に配置して、メールセッションリソースの初期化中に Tomcat で使用できるようにします。注:この jar を $CATALINA_HOME/lib と Web アプリケーションの lib フォルダーの両方に配置するとエラーが発生するため、$CATALINA_HOME/lib の場所にのみ配置されていることを確認してください。
5. 互換性のある実装をインストールする
互換性のある実装を選択して ダウンロード します。
実装を解凍し、jar ファイルを $CATALINA_HOME/lib に配置します。
注:他の実装が利用可能な場合があります
6. Tomcat を再起動します
追加の JAR を Tomcat で認識できるようにするには、Tomcat インスタンスを再起動する必要があります。
アプリケーション例
Tomcat に含まれている /examples
アプリケーションには、このリソースファクトリを使用する例が含まれています。「JSP Examples」リンクからアクセスします。メールメッセージを実際に送信するサーブレットのソースコードは、/WEB-INF/classes/SendMailServlet.java
にあります。
警告 - デフォルト構成では、localhost
のポート 25 でリッスンしている SMTP サーバーがあると想定しています。そうでない場合は、この Web アプリケーションの <Context>
要素を編集し、mail.smtp.host
パラメーターのパラメーター値をネットワーク上の SMTP サーバーのホスト名に変更します。
JDBC データソース
0. はじめに
多くの Web アプリケーションは、そのアプリケーションに必要な機能をサポートするために、JDBC ドライバーを介してデータベースにアクセスする必要があります。Jakarta EE プラットフォームの仕様では、Jakarta EE アプリケーションサーバーはこの目的のために *DataSource* 実装(つまり、JDBC 接続の接続プール)を利用できるようにする必要があります。Tomcat はまったく同じサポートを提供しているため、このサービスを使用して Tomcat で開発したデータベースベースのアプリケーションは、どの Jakarta EE サーバーでも変更なしで実行されます。
JDBC については、以下を参照してください。
- http://www.oracle.com/technetwork/java/javase/jdbc/index.html - Java Database Connectivity に関する情報のホームページ。
- http://java.sun.com/j2se/1.3/docs/guide/jdbc/spec2/jdbc2.1.frame.html - JDBC 2.1 API 仕様。
- http://java.sun.com/products/jdbc/jdbc20.stdext.pdf - JDBC 2.0 標準拡張 API(
javax.sql.DataSource
API を含む)。このパッケージは、現在「JDBC オプションパッケージ」と呼ばれています。 - https://jakarta.ee/specifications/platform/9/ - Jakarta EE プラットフォーム仕様(すべての Jakarta EE プラットフォームがアプリケーションに提供する必要がある JDBC 機能を網羅しています)。
注 - Tomcat のデフォルトのデータソースサポートは、Commons プロジェクトの **DBCP 2** 接続プールに基づいています。ただし、以下で説明するように、独自のカスタムリソースファクトリを作成することにより、javax.sql.DataSource
を実装する他の接続プールを使用することができます。
1. JDBC ドライバーのインストール
*JDBC データソース* JNDI リソースファクトリを使用するには、適切な JDBC ドライバーを Tomcat 内部クラスと Web アプリケーションの両方に使用できるようにする必要があります。これは、ドライバーの JAR ファイルを `$CATALINA_HOME/lib` ディレクトリにインストールすることで最も簡単に行えます。これにより、ドライバーはリソースファクトリとアプリケーションの両方で使用できるようになります。
2. リソース要件を宣言する
次に、Web アプリケーションのデプロイメント記述子(`/WEB-INF/web.xml`)を変更して、事前に設定されたデータソースを検索する JNDI 名を宣言します。慣例により、そのようなすべての名前は、すべての提供されたリソースファクトリのルートである標準の `java:comp/env` ネーミングコンテキストを基準とした `jdbc` サブコンテキストに解決される必要があります。典型的な `web.xml` エントリは次のようになります。
<resource-ref>
<description>
Resource reference to a factory for java.sql.Connection
instances that may be used for talking to a particular
database that is configured in the <Context>
configuration for the web application.
</description>
<res-ref-name>
jdbc/EmployeeDB
</res-ref-name>
<res-type>
javax.sql.DataSource
</res-type>
<res-auth>
Container
</res-auth>
</resource-ref>
警告 - Web アプリケーションのデプロイメント記述子の DTD で必要な要素の順序を必ず守ってください! 詳細については、サーブレット仕様 を参照してください。
3. このリソースを使用するアプリケーションのコードを作成する
このリソース参照の一般的な使用法は次のようになります。
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
アプリケーションは、Web アプリケーションのデプロイメント記述子で宣言されたのと同じリソース参照名を使用していることに注意してください。これは、以下で説明するように、Web アプリケーションの <Context>
要素で設定されているリソースファクトリと照合されます。
4. Tomcat のリソースファクトリを設定する
Tomcat のリソースファクトリを設定するには、Web アプリケーションの `<Context>` 要素に次のような要素を追加します。
<Context ...>
...
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="dbusername"
password="dbpassword"
driverClassName="org.hsql.jdbcDriver"
url="jdbc:HypersonicSQL:database"
maxTotal="8"
maxIdle="4"/>
...
</Context>
リソース名(ここでは `jdbc/EmployeeDB`)は、Web アプリケーションのデプロイメント記述子で指定された値と一致する必要があることに注意してください。
この例では、HypersonicSQL データベース JDBC ドライバを使用していることを前提としています。実際のデータベースの JDBC ドライバと接続 URL に合わせて、driverClassName
パラメータと driverName
パラメータをカスタマイズしてください。
Tomcat の標準データソースリソースファクトリ (org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory
) の構成プロパティは次のとおりです。
- driverClassName - 使用する JDBC ドライバの完全修飾 Java クラス名。
- username - JDBC ドライバに渡すデータベースユーザー名。
- password - JDBC ドライバに渡すデータベースパスワード。
- url - JDBC ドライバに渡す接続 URL。(下位互換性のために、
driverName
プロパティも認識されます。) - initialSize - プール初期化中にプールに作成される初期接続数。デフォルト:0
- maxTotal - このプールから同時に割り当てることができる最大接続数。デフォルト:8
- minIdle - このプールに同時にアイドル状態になる最小接続数。デフォルト:0
- maxIdle - このプールに同時にアイドル状態になることができる最大接続数。デフォルト:8
- maxWaitMillis - 使用可能な接続がない場合に、プールが接続が返されるのを待つ最大ミリ秒数。これを超えると例外がスローされます。デフォルト:-1(無限)
接続の検証を処理する追加のプロパティがあります。
- validationQuery - アプリケーションに返される前に、プールが接続を検証するために使用できる SQL クエリ。指定する場合、このクエリは少なくとも 1 行を返す SQL SELECT ステートメントでなければなりません。
- validationQueryTimeout - 検証クエリのタイムアウト(秒単位)。デフォルト:-1(無限)
- testOnBorrow - true または false:プールから接続を借りるたびに、検証クエリを使用して接続を検証するかどうか。デフォルト:true
- testOnReturn - true または false:プールに接続を返すたびに、検証クエリを使用して接続を検証するかどうか。デフォルト:false
オプションのエビクタースレッドは、長時間アイドル状態になっている接続を削除することにより、プールの縮小を行います。エビクターは minIdle
を考慮しません。設定された maxIdle
プロパティに従ってプールを縮小する場合のみ、エビクタースレッドをアクティブにする必要はありません。
エビクターはデフォルトで無効になっており、次のプロパティを使用して設定できます。
- timeBetweenEvictionRunsMillis - エビクターの連続実行の間隔(ミリ秒単位)。デフォルト:-1(無効)
- numTestsPerEvictionRun - エビクターの実行ごとに、エビクターがアイドル状態を確認する接続の数。デフォルト:3
- minEvictableIdleTimeMillis - エビクターがプールから接続を削除できるアイドル時間(ミリ秒単位)。デフォルト:30*60*1000(30分)
- testWhileIdle - true または false:プールにアイドル状態になっている間に、エビクタースレッドが検証クエリを使用して接続を検証するかどうか。デフォルト:false
もう 1 つのオプション機能は、放棄された接続の削除です。アプリケーションが長時間プールに接続を返さない場合、接続は放棄されたと呼ばれます。プールは、このような接続を自動的に閉じてプールから削除できます。これは、アプリケーションが接続をリークする場合の回避策です。
放棄機能はデフォルトで無効になっており、次のプロパティを使用して設定できます。
- removeAbandonedOnBorrow - true または false:接続が借用されたときに、放棄された接続をプールから削除するかどうか。デフォルト:false
- removeAbandonedOnMaintenance - true または false:プールメンテナンス中に、放棄された接続をプールから削除するかどうか。デフォルト:false
- removeAbandonedTimeout - 借用された接続が放棄されたとみなされるまでの秒数。デフォルト:300
- logAbandoned - true または false:ステートメントまたは接続を放棄したアプリケーションコードのスタックトレースをログに記録するかどうか。これは深刻なオーバーヘッドを追加します。デフォルト:false
最後に、プールの動作をさらに微調整できるさまざまなプロパティがあります。
- defaultAutoCommit - true または false:このプールによって作成された接続のデフォルトの自動コミット状態。デフォルト:true
- defaultReadOnly - true または false:このプールによって作成された接続のデフォルトの読み取り専用状態。デフォルト:false
- defaultTransactionIsolation - デフォルトのトランザクション分離レベルを設定します。
NONE
、READ_COMMITTED
、READ_UNCOMMITTED
、REPEATABLE_READ
、SERIALIZABLE
のいずれかになります。デフォルト:デフォルト設定なし - poolPreparedStatements - true または false:PreparedStatement と CallableStatement をプールするかどうか。デフォルト:false
- maxOpenPreparedStatements - ステートメントプールから同時に割り当てることができるオープンステートメントの最大数。デフォルト:-1(無制限)
- defaultCatalog - デフォルトカタログの名前。デフォルト:設定なし
- connectionInitSqls - 接続の作成後に一度だけ実行される SQL ステートメントのリスト。複数のステートメントはセミコロン(
;
)で区切ります。デフォルト:ステートメントなし - connectionProperties - 接続を作成するためにドライバに渡されるドライバ固有のプロパティのリスト。各プロパティは
name=value
として指定され、複数のプロパティはセミコロン(;
)で区切られます。デフォルト:プロパティなし - accessToUnderlyingConnectionAllowed - true または false:基になる接続へのアクセスを許可するかどうか。デフォルト:false
詳細については、Commons DBCP 2 のドキュメントを参照してください。
カスタムリソースファクトリの追加
標準のリソースファクトリがいずれもニーズを満たさない場合は、独自のファクトリを作成して Tomcat に統合し、Web アプリケーションの <Context>
要素でこのファクトリの使用を設定できます。以下の例では、上記の汎用 JavaBean リソースの例から com.mycompany.MyBean
Bean のみを 作成する方法を知っているファクトリを作成します。
1. リソースファクトリクラスを作成する
JNDI サービスプロバイダ javax.naming.spi.ObjectFactory
インターフェースを実装するクラスを作成する必要があります。Web アプリケーションがこのファクトリにバインドされているコンテキストエントリで lookup()
を呼び出すたびに(ファクトリが singleton="false"
で構成されていると仮定)、getObjectInstance()
メソッドが次の引数で呼び出されます。
- Object obj - オブジェクトの作成に使用できる、場所または参照情報を含む(null の可能性もある)オブジェクト。Tomcat の場合、これは常に
javax.naming.Reference
型のオブジェクトであり、このファクトリクラスのクラス名と、返すオブジェクトの作成に使用する構成プロパティ(Web アプリケーションの<Context>
から)が含まれます。 - Name name - このファクトリが
nameCtx
に対してバインドされている相対名。名前が指定されていない場合はnull
。 - Context nameCtx -
name
パラメータが指定されている相対コンテキスト。name
がデフォルトの初期コンテキストに対する相対名である場合はnull
。 - Hashtable environment - このオブジェクトの作成に使用される(null の可能性もある)環境。これは一般に Tomcat オブジェクトファクトリでは無視されます。
MyBean
インスタンスを生成する方法を知っているリソースファクトリを作成するには、次のようなクラスを作成します。
package com.mycompany;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
public class MyBeanFactory implements ObjectFactory {
public Object getObjectInstance(Object obj,
Name name2, Context nameCtx, Hashtable environment)
throws NamingException {
// Acquire an instance of our specified bean class
MyBean bean = new MyBean();
// Customize the bean properties from our attributes
Reference ref = (Reference) obj;
Enumeration addrs = ref.getAll();
while (addrs.hasMoreElements()) {
RefAddr addr = (RefAddr) addrs.nextElement();
String name = addr.getType();
String value = (String) addr.getContent();
if (name.equals("foo")) {
bean.setFoo(value);
} else if (name.equals("bar")) {
try {
bean.setBar(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new NamingException("Invalid 'bar' value " + value);
}
}
}
// Return the customized instance
return (bean);
}
}
この例では、com.mycompany.MyBean
クラスの新しいインスタンスを無条件に作成し、このファクトリを構成する <ResourceParams>
要素に含まれるパラメータに基づいてそのプロパティを設定しています(下記参照)。factory
という名前のパラメータはスキップする必要があることに注意してください。このパラメータは、構成されている Bean のプロパティではなく、ファクトリクラス自体の名前(この場合は com.mycompany.MyBeanFactory
)を指定するために使用されます。
ObjectFactory
の詳細については、JNDI サービスプロバイダインターフェース(SPI)仕様を参照してください。
このクラスは、$CATALINA_HOME/lib
ディレクトリにあるすべての JAR ファイルを含むクラスパスに対してコンパイルする必要があります。完了したら、ファクトリクラス(および対応する Bean クラス)を $CATALINA_HOME/lib
の下に展開するか、$CATALINA_HOME/lib
内の JAR ファイルに配置します。このようにして、必要なクラスファイルは Catalina 内部リソースと Web アプリケーションの両方から参照できます。
2. リソース要件を宣言する
次に、Web アプリケーションのデプロイメント記述子(/WEB-INF/web.xml
)を変更して、この Bean の新しいインスタンスを要求する JNDI 名を宣言します。最も簡単な方法は、次のように <resource-env-ref>
要素を使用することです。
<resource-env-ref>
<description>
Object factory for MyBean instances.
</description>
<resource-env-ref-name>
bean/MyBeanFactory
</resource-env-ref-name>
<resource-env-ref-type>
com.mycompany.MyBean
</resource-env-ref-type>
</resource-env-ref>
警告 - Web アプリケーションのデプロイメント記述子の DTD で必要な要素の順序を必ず守ってください! 詳細については、サーブレット仕様 を参照してください。
3. このリソースを使用するアプリケーションのコードを作成する
このリソース環境参照の一般的な使用例は次のとおりです。
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
writer.println("foo = " + bean.getFoo() + ", bar = " +
bean.getBar());
4. Tomcat のリソースファクトリを設定する
Tomcat のリソースファクトリを設定するには、この Web アプリケーションの <Context>
要素に次のような要素を追加します。
<Context ...>
...
<Resource name="bean/MyBeanFactory" auth="Container"
type="com.mycompany.MyBean"
factory="com.mycompany.MyBeanFactory"
singleton="false"
bar="23"/>
...
</Context>
リソース名(ここでは bean/MyBeanFactory
)は、Web アプリケーションのデプロイメント記述子で指定された値と一致する必要があることに注意してください。また、bar
プロパティの値を初期化しています。これにより、新しい Bean が返される前に setBar(23)
が呼び出されます。 foo
プロパティは初期化していないため(初期化することもできます)、Bean にはコンストラクタによって設定されたデフォルト値が格納されます。
また、アプリケーション開発者の観点からは、リソース環境参照の宣言と、新しいインスタンスを要求するために使用されるプログラミングは、_汎用 JavaBean リソース_ の例で使用されるアプローチと同じです。これは、JNDI リソースを使用して機能をカプセル化する利点の 1 つを示しています。互換性のある API を維持する限り、リソースを使用するアプリケーションを変更せずに、基になる実装を変更できます。