JNDIとデータベース・リソース

JNDIとデータベース・リソース
 JNDI(Java Naming and Directory Interface)とは、 Javaアプリケーションにおいて、リソースにつけられた名前から、 それが指すリソースを特定し、アクセスできるようにする「名前解決」の仕組みです。 ここでいうリソースとは、Javaアプリケーションが利用する情報源で、 自分自身以外に由来するものです。 業務アプリケーションで必要となる代表的にリソースは2つあり、 事例、サンプルでもしばしばとりあげられます。 ひとつはJavaMail APIを使って電子メールを送信する際のメールサーバ (SMTPホスト)を特定する情報(javax.mail.Session)、 そしてもうひとつは皆さんよくご存知のデータベースを特定する情報(javax.sql.DataSource)です。 ここではまず、JNDIを使ってデータベースをリソースとしてアクセスする方法について、 簡単にメモっています。

 サーブレットコンテナに載っているアプリケーションで、 あるデータベースにJNDI経由でアクセスできるようにする手順は、次の通りです。

  1. サーブレットコンテナのシステム設定ファイル (Jakarta Tomcatならserver.xml、BXSならsystem.xmlなどなど) に、リソースの名前とそれが指すデータベース・リスナーへの接続情報を書く。
  2. Webアプリケーションの設定ファイル(web.xml)で、 サーブレットなどがアクセスするリソースの名前とそのデータ型 (Javaクラス名)を書く。
  3. 実際に、JNDIでリソースにアクセスするアプリケーションを開発する。

サーブレットコンテナの設定
 サーブレットコンテナ側の設定はコンテナによって異なります。 ここではJakarta Tomcat 4.1.x〜5.0.xの設定ファイル($CATALINA_HOME/conf/server.xml) の記述例を紹介します。

<Context path="/app01" docBase="C:/usr/javadeploy/app01" debug="0" reloadable="true">
  <Logger className="org.apache.catalina.logger.FileLogger"
          prefix="app01." suffix=".txt" timestamp="true"/>
  <Resource name="jdbc/mudb" auth="Container" type="javax.sql.DataSource"/>
  <ResourceParams name="jdbc/mudb">
      <parameter><name>username</name><value>urano</value></parameter>
      <parameter><name>password</name><value>urano398</value></parameter>
      <parameter><name>driverClassName</name>
        <value>com.mysql.jdbc.Driver</value></parameter>
      <parameter><name>url</name>
        <value>jdbc:mysql://localhost/udb?useUnicode=true&characterEncoding=SJIS</value></parameter>
  </ResourceParams>
</Context>

(※注:url属性の値の中に、&という文字がありますが、 これはXMLファイルでは&amp;(←Webブラウザで見えているまま)と書きます)
 このように、利用したいアプリケーションコンテキスト(ここでは/app01) の中で、ResourceタグとResourceParams タグを対にして記述します。
 リソースの名前は、データベース・リソースの場合「jdbc」を冠するのが慣習で、 ここでは「jdbc/mudb」としています。
 ResourceParamsタグの中には、実際にそのデータベースに接続するために必要な情報を記述します。 これはどのデータベースでも共通で、上の例で大体網羅していると思います。
(注:「username」「url」は以前のバージョンではそれぞれ 「user」「driverName」とされていました。 そのため、書籍によってこちらの記述を使われている場合もあります。 Tomcatでは、ドキュメントには「後方互換性のために残されている」と書かれていますが、 実際に新しいバージョンのTomcatでuserやdriverNameを使うと既に認識されなくなっています。)
com.mysql.jdbc.Driver はMySQL ABが配布している、MySQL用のJDBCドライバの名前で、 他のデータベースの場合はそれに合わせたものを入手し、それを指定します。
 なお、これはcom.mysql.jdbc.Driverだけの事情ですが、 このJDBCドライバではURLに上記の?以下のオプションを指定しないと、 JDBCのResultSetMetaDataオブジェクトを使った列名の参照がうまくできません。 その場合にURLに&文字を含める必要がありますが、これは&amp;とエスケープします。

Webアプリケーションの設定
 アプリケーションの設定はWEB-INF/web.xmlの中で次のように行います。

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

 アプリケーション側で設定する必要があるものはこれだけです。 つまるところ、
  • このアプリケーションは「jdbc/udb」というリソースを使うのです。
  • それはjavax.sql.DataSourceクラスのオブジェクトです。
これだけのことをアプリケーションからコンテナに伝えておけば、 後はコンテナの方が実際のリソースとのやりとりを行ってくれます。 この最大の恩恵は、Webアプリケーションがコンテナの制約を受けない、 ということです。例えば、オープンソースのコンテナの元で開発を進め、 実際の運用にはロードバランサーなどを備えた市販のコンテナを使う、等のことが可能です。

プログラムの中から
 サーブレットなどのアプリケーション・プログラムの中では、 先述の通り、「これこれのリソースが必要です」と発すると、 コンテナが設定にもとづき適切なリソースを探して返してきます。

  try {
    Context c = new InitialContext();
    DataSource ds = (DataSource) c.lookup(jndiName);
    Connection conn = ds.getConnection();
  } catch(NamingException ex){
    throw new SQLException(
"cannot lookup database resource from jndi namespace: " + ex.toString());
    }
  }

 リソースを探すメソッドはjavax.naming.Context.lookup ですが、そのとき指定するのはリソースの名前ではなくJNDI名と呼ばれるものです。 サーブレットで使うJNDI名は、サーブレットの規約により、 「java:comp/env/リソース名」と決められています。 従ってこの例では、「java:comp/env/jdbc/udb」となります。

JDBC and Swing Top

(first uploaded 2002/03/02 last updated 2004/07/25, KQ TAURA - URANO398)

楽天モバイル[UNLIMITが今なら1円] ECナビでポインと Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!


無料ホームページ 無料のクレジットカード 海外格安航空券 解約手数料0円【あしたでんき】 海外旅行保険が無料! 海外ホテル