Seasar - Tomcat のコネクションプーリングを使用する

失敗

Tomcat のコネクションプーリングを使用するために、DB 接続情報を定義した context.xml を作成し、META-INF ディレクトリに配置しました。 ところが、Web アプリをデプロイしてみると NullPointerException が発生してしまいます (スタックトレース) 。

jdbc.dicon などの設定も終わっているはずなのに、いったい何が問題なのでしょうか?

環境

このレポートは、以下の環境について記述したものです。

JDK Java SE Development Kit 6 Update 16
AP サーバ Tomcat 6.20
Seasar
  • S2Container 2.4.39
  • S2JDBC-Gen 2.4.39
Dolteng プラグイン Dolteng 0.39
DBMS MySQL 5.1
JDBC Connector/J 5.1.10

スタックトレース

S2JDBC-Gen 実行時のスタックトレース

原因

原因は context.xml の配置場所を誤るという、恥ずかしいものでした。
・・・ <プロジェクト・ルート>/src/main/webapp/META-INF/context.xml
× ・・・ <プロジェクト・ルート>/src/main/resources/META-INF/context.xml

解決策

Tomcat のコネクションプーリングを使用するための設定手順を示します。

(1) context.xml の作成

<プロジェクト・ルート>/src/main/webapp/META-INF ディレクトリに context.xml を作成します。 内容は DB への接続情報です。

[src/main/webapp/META-INF/context.xml - DB への接続情報を定義する]
<Context>
	<WatchedResource>WEB-INF/web.xml</WatchedResource>
	<Resource name="jdbc/my_ds"
		type="javax.sql.DataSource"
		driverClassName="com.mysql.jdbc.Driver"
		username="root"
		password="password"
		url="jdbc:mysql://127.0.0.1:3306/mydb"
		auth="Container"
		maxActive="25"
		maxIdle="4"
		maxWait="10000"
	/>
</Context>

Resource 要素の属性を下表に示します。

属性 説明
name JNDI リソース名 (任意)
type リソースのクラス or インターフェイス名
driverClassName JDBC ドライバのクラス名
username DB のユーザ名
password DB のパスワード
url DB の接続 URL
auth Application ・・・ アプリケーション管理
Container ・・・ コンテナ管理
maxActive DB 接続の最大接続数。0 で無限大。
maxIdle アイドル状態の接続の最大数。0 で無限大。
maxWait プールに利用可能な接続がない場合に、利用可能な接続ができるまで待つ時間 (ミリ秒単位) 。-1 で無制限。

(2) web.xml の編集

web.xml に resource-ref 要素を追加し、context.xml で定義したデータソースへの参照ルックアップ名を追加します。 子要素の res-ref-name 要素には、(1) の name に指定した JNDI リソース名を指定します。 これにより、java:comp/env/ からの相対パスで参照できるようになります。

[src/main/webapp/WEB-INF/web.xml - データソースへの参照ルックアップ名を追加する]
<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
	<!-- 省略 -->

	<resource-ref>
		<res-ref-name>jdbc/my_ds</res-ref-name>
		<res-type>javax.sql.DataSource</res-type>
		<res-auth>Container</res-auth>
	</resource-ref>
</web-app>

(3) jdbc.dicon の編集

jdbc.dicon には、JDBC データソースを定義します。 (1) ~ (2) で定義したデータソースを使用するように変更すれば、Tomcat のコネクションプーリングを使用できます。

ただ、このファイルを直接変更すると、常に Tomcat からデータソースを取得するようになり、S2JDBC-Gen が動作しなくなります。 この問題を避けるため、jdbc.dicon にデータソースを定義せず、環境定義 (env.txt の値) に応じて別の設定ファイルを読み込むようにします。

env.txt が product の場合
jdbc_product.dicon を読み込み、Tomcat のコネクションプーリングを使用します。
env.txt が product 以外の場合
jdbc_ut.dicon を読み込み、S2DBCP を使用します。
[src/main/resources/jdbc.dicon - 環境定義に応じて設定を切り替える]
<?xml version="1.0"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
  "http://www.seasar.org/dtd/components24.dtd">
<components>
	<include condition="#ENV == 'product'" path="jdbc_product.dicon"/>
	<include condition="#ENV != 'product'" path="jdbc_ut.dicon"/>
</components>

(4) jdbc_product.dicon の作成

Tomcat のコネクションプールからデータソースを取得します。 JndiResourceLocator@lookup に web.xml で設定した参照ルックアップ名を指定します (本例では java:comp/env/jdbc/my_ds) 。

[src/main/resources/jdbc_product.dicon - Tomcat のコネクションプーリングを使用する]
<?xml version="1.0"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
  "http://www.seasar.org/dtd/components24.dtd">
<components namespace="jdbc">
	<include path="jta.dicon"/>
	<include path="jdbc-extension.dicon"/>
	
	<component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>
	<component class="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory">
		<arg>
			<component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>
		</arg>
		<property name="fetchSize">100</property>
		<!--
		<property name="maxRows">100</property>
		-->
	</component>

	<component name="DataSource"
		class="javax.sql.DataSource">
		@org.seasar.extension.j2ee.JndiResourceLocator@lookup("java:comp/env/jdbc/my_ds")
	</component>
</components>

(5) jdbc_ut.dicon の作成

S2DBCP を使用して、データソースを取得します。 driverClassName、URL、user、password を環境に合わせて、変更してください。

[src/main/resources/jdbc_ut.dicon - S2DBCP を使用する]
<?xml version="1.0"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
  "http://www.seasar.org/dtd/components24.dtd">
<components>
	<include path="jta.dicon"/>

	<component name="xaDataSource"
		class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
		<property name="driverClassName">
			"com.mysql.jdbc.Driver"
		</property>
		<property name="URL">
			"jdbc:mysql://localhost:3306/mydb"
		</property>
		<property name="user">"root"</property>
		<property name="password">"password"</property>
	</component>

	<component name="connectionPool"
		class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
		<property name="timeout">600</property>
		<property name="maxPoolSize">10</property>
		<property name="allowLocalTx">true</property>
		<destroyMethod name="close"/>
	</component>

	<component name="DataSource"
		class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>
</components>

(6) Connector/J の配置

最後に JDBC ドライバを配置します。 本稿では MySQL 用の Connector/J (mysql-connector-java-5.1.10-bin.jar) を使用します。

Tomcat 用
<CATALINA_HOME>/lib ディレクトリに配置します。
S2DBCP 用
<プロジェクト・ルート>/src/main/webapp/WEB-INF/lib ディレクトリに配置します。

以上で設定は完了です。 env.txt を product にすれば、Tomcat のコネクションプーリングを使用するようになります。

補足

■ S2JDBC-Gen の環境定義

S2JDBC-Gen が実行される環境は env パラメータで指定できます。 Dolteng でプロジェクトを作成した場合は、デフォルトで ut になっています。

[s2jdbc-gen-build.xml - env のデフォルト値]
<project name="mysample-s2jdbc-gen" default="gen-ddl" basedir=".">
	<!-- 省略 -->
	<property name="env" value="ut"/>
	<!-- 省略 -->
<project>

参考サイト

コメント

コメント投稿
(非公開)
     « アイコン一覧 »
(必須)

作成日:2009/10/15
更新日:2009/10/15