Sun ONE Application Server 7, Update 1 管理者ガイド |
この章では、Sun ONE Application Server が使用する J2EE リソースについて、およびリソースの作成と管理に使われるメソッドについて説明します。
この章では次のトピックについて説明します。
- J2EE ネーミングサービスとリソースについて
- JNDI (Java Naming and Directory Interface) について
- 持続マネージャリソースについて
- JDBC リソースについて
- JavaMail リソースについて
J2EE ネーミングサービスとリソースについて
Enterprise JavaBean、Web アプリケーションコンポーネント、アプリケーションクライアントなどの J2EE アプリケーションは、リソースマネージャ、データソース (SQL データソースなど)、接続ファクトリ、メールセッション、Java Message Service 送信先オブジェクト、URL 接続ファクトリなど、多様なリソースにアクセスします。J2EE プラットフォームは、JNDI (Java Naming and Directory Interface) ネーミングサービスを通じてアプリケーションにリソースを渡します。
Sun ONE Application Server では、次の J2EE リソースを作成、管理できます。
JDBC データソース
JDBC データソースは、Sun ONE Application Server を使って作成、管理できる J2EE リソースです。
JDBC API は、リレーショナルデータベースシステムとの接続に使われる API です。JDBC API は、次の 2 つから構成されます。
- アプリケーションコンポーネントがデータベースへのアクセスに使うアプリケーションレベルのインタフェース
- JDBC ドライバを J2EE プラットフォームに接続するためのサービスプロバイダインタフェース
JDBC DataSource オブジェクトは、Java プログラミング言語で記述されたデータソースを意味します。データソースは、基本的にはデータを格納するための機能です。大企業の複雑なデータベースのように洗練されている場合もあれば、行と列だけを含む簡単なファイルである場合もあります。JDBC データソースは、Sun ONE Application Server を使って作成、管理できる J2EE リソースです。
JDBC データソースの詳細については、「JDBC リソースについて」を参照してください。
Java Mail セッション
JMS 送信先は、Sun ONE Application Server を使って作成、管理できる J2EE リソースです。
多くのインターネットアプリケーションでは、電子メール通知を送信する機能を必要とするため、J2EE プラットフォームには、JavaMail API と、アプリケーションコンポーネントがインターネットメールを送信するための JavaMail サービスプロバイダが含まれています。JavaMail API は、次の 2 つから構成されます。
- アプリケーションコンポーネントがメールの送信に使うアプリケーションレベルのインタフェース
- J2EE SPI レベルで使われるサービスプロバイダインタフェース
Java Mail セッションは、Sun ONE Application Server を使って作成、管理できる J2EE リソースです。Java Mail セッションの詳細については、「JavaMail リソースについて」を参照してください。
JMS 送信先
JMS (Java Messaging Service) は、信頼性の高いポイントツーポイントのメッセージングとパブリッシュ - サブスクライブモデルをサポートする標準 API です。この仕様では、ポイントツーポイントのメッセージングとパブリッシュ - サブスクライブのメッセージングの両方を実装した JMS プロバイダが必要です。
JMS は、接続ファクトリオブジェクトと送信先オブジェクトという 2 つの一般的な管理対象オブジェクトを提供します。どちらのオブジェクトもプロバイダ固有の情報をカプセル化しますが、JMS クライアント内での使用方法はまったく異なっています。接続ファクトリオブジェクトは、メッセージサーバーへの接続の確立に使用されます。一方、送信先オブジェクトは、JMS メッセージングサービスによって使用される物理的な送信先の識別に使用されます。
JNDI (Java Naming and Directory Interface) について
この節では、JNDI (Java Naming and Directory Interface) について説明します。JNDI は、多様なネーミングサービスとディレクトリサービスにアクセスするための API (アプリケーションプログラミングインタフェース) です。J2EE コンポーネントは、JNDI ルックアップメソッドを呼び出してオブジェクトの場所を特定します。
この節には次の項目があります。
JNDI アーキテクチャ
JNDI アーキテクチャは、API と SPI (Service Provider Interface) から構成されます。Java アプリケーションは JNDI API を使って各種ネーミングサービスとディレクトリサービスにアクセスします。SPI を使うことで、さまざまなネーミングサービスとディレクトリサービスを透過的にプラグインできるので、JNDI API を使う Java アプリケーションはこれらのサービスにアクセスできます。次の図「JNDI アーキテクチャの概要」は、JNDI API を通じてアクセスできるサービスを示しています。
   JNDI アーキテクチャの概要
J2EE ネーミングサービス
JNDI 名は、人間が理解しやすいオブジェクト名です。この名前は、J2EE サーバーのネーミングサービスとディレクトリサービスによってオブジェクトに結びつけられます。J2EE コンポーネントは JNDI API を介してこのサービスにアクセスするため、人間が理解しやすいオブジェクト名を通常は JNDI 名と呼んでいます。Pointbase データベースの JNDI 名は、jdbc/Pointbase です。Sun ONE Application Serverを起動すると、設定ファイルの情報が読み込まれ、名前スペースには JNDI データベース名が自動的に追加されます。
J2EE アプリケーションクライアント、Enterprise JavaBean、Web コンポーネントは、JNDI ネーミング環境へのアクセスが必要です。
アプリケーションコンポーネントのネーミング環境は、配備時またはアセンブリ時にアプリケーションコンポーネントのビジネスロジックをカスタマイズするためのメカニズムです。アプリケーションコンポーネントの環境を利用することで、アプリケーションコンポーネントのソースコードにアクセスしたり、それを変更したりすることなく、アプリケーションコンポーネントをカスタマイズできます。
J2EE コンテナはアプリケーションコンポーネントの環境を実装し、それを JNDI ネーミングコンテキストとしてアプリケーションコンポーネントに提供します。アプリケーションコンポーネントの環境は、次のように使用されます。
- アプリケーションコンポーネントのビジネスメソッドが JNDI インタフェースを使って環境にアクセスする。アプリケーションコンポーネントプロバイダは、実行時のアプリケーションコンポーネントの環境に提供されるすべての環境エントリを配備記述子に宣言する
- コンテナは、アプリケーションコンポーネントの環境を格納した JNDI ネーミングコンテキストの実装を提供する。また、配備担当者が各アプリケーションコンポーネントの環境を作成、管理できるように、コンテナはツールも提供する
- 配備担当者は、コンテナから提供されるツールを使ってアプリケーションコンポーネントの配備記述子に宣言された環境エントリを初期化する。配備担当者は、環境エントリの値を設定、変更できる
- コンテナは、実行時にアプリケーションコンポーネントインスタンスが利用できる環境ネーミングコンテキストを作成する。アプリケーションコンポーネントのインスタンスは、JNDI インタフェースを使って環境エントリの値を取得する
各アプリケーションコンポーネントは、それぞれに固有の環境エントリセットを定義します。同じコンテナに含まれるアプリケーションコンポーネントのすべてのインスタンスは、同じ環境エントリを共有します。アプリケーションコンポーネントインスタンスが実行時に環境を変更することはできません。Web コンテナや Enterprise JavaBean コンテナなどの J2EE コンテナが JNDI ネーミングサービスを使ってオブジェクトをルックアップする仕組みについては、「J2EE コンテナの設定」を参照してください。
ネーミング参照とバインド情報
リソース参照は、配備記述子の要素の 1 つであり、そのリソースのコンポーネントのコード名を識別します。具体的には、コード化された名前がリソースの接続ファクトリを参照します。次の項の例では、リソースの参照名は jdbc/SavingsAccountDB です。
リソースの JNDI 名とリソース参照の名前は同じではありません。この命名方法では、配備前に 2 つの名前をマッピングする必要がありますが、さらに、リソースからコンポーネントを切り離すことも必要です。コンポーネントを切り離しておくと、あとでそのコンポーネントが別のリソースにアクセスする必要が生じた場合に、コード内の名前を変更する必要がありません。また、既存のコンポーネントから J2EE アプリケーションを編成する作業も容易になります。
次の表の「JNDI ルックアップとそれに対応する参照」は、JNDI ルックアップと、Sun ONE Application Server が使用する J2EE リソースの参照の対応を示しています。
J2EE 標準配備記述子でのネーミング参照
ネーミング参照は、指定されたネーミングコンテキストからアプリケーションがオブジェクトをルックアップするための文字列です。各 J2EE アプリケーションの標準のコンポーネント配備記述子には、ネーミングコンテキストと参照が設定されています。この項では、Sun ONE Application Server で使われる標準の配備記述子の機能について説明します。この節には次の項目があります。
アプリケーション環境エントリ
<env-entry> を使って定義される環境エントリは、配備時のパラメータを J2EE アプリケーションに指定します。Web アプリケーションでは、<context-param> を使ってサーブレットコンテキストの初期化パラメータを定義できますが、アプリケーションの配備担当者が名前、タイプ、値を指定して明示的にアプリケーションパラメータを設定できるので、<env-entry> を使うことをお勧めします。
次の例は、J2EE 標準配備記述子に指定する <env-entry> の構文を示しています。
<env-entry>
<description> Send pincode by mail </description>
<env-entry-name> mailPincode </env-entry-name>
<env-entry-value> false </env-entry-value>
<env-entry-type> java.lang.Boolean </env-entry-type>
</env-entry><env-entry-type> タグは、エントリの完全修飾クラス名を指定しています。アプリケーションコンポーネントから JNDI (サーブレット / JSP または エンティティ Bean を参照する、または IIOP アプリケーションクライアントを参照する) を使って <env-entry> をルックアップするコード例は次のとおりです。
Context initContext = new InitialContext();
Boolean mailPincode = (Boolean)
initContext.lookup("java:comp/env/mailPincode");// サブコンテキストでは相対名を使用できる
Context envContext = initContext.lookup("java:comp/env");
Boolean mailPincode = (Boolean)
envContext.lookup("mailPincode");EJB 参照
JNDI ネーミングサービスにより、配備記述子のサポートとは別に、アプリケーションは「論理」名 (EJB 参照) を使って Enterprise JavaBean のホームインタフェースにマップすることができます。次に例を示します。
<ejb-ref>
<ejb-ref-name> ejb/EmplRecord </ejb-ref-name>
<ejb-ref-type> Entity </ejb-ref-type>
<home> com.wombat.empl.EmployeeRecordHome </home>
<remote> com.wombat.empl.EmployeeRecord </remote>
<ejb-link> EmployeeEJB </ejb-link>
</ejb-ref>次の例に示すように、JSP などのアプリケーションコンポーネントは、JNDI を使って Enterprise JavaBean ホームオブジェクトにアクセスできます。
Context initContext = new InitialContext();
Context envContext = initContext.lookup("java:comp/env");
Object result = envContext.lookup("ejb/EmplRecord");
EmployeeRecordHome emplRecordHome = (EmployeeRecordHome)
javax.rmi.PortableRemoteObject.narrow(result, EmployeeRecordHome.class);ejb-ref-name 要素は、アプリケーションコードで使われる文字列を定義します (上記の例を参照)。ejb-link 要素は、ejb-jar.xml に定義されているエンティティ Bean の ejb-name 要素を使って定義されるターゲット Enterprise JavaBean にこの参照をリンクします。また、アプリケーション配備記述子または Enterprise JavaBean 配備記述子を変更せずにリンクすることもできます。
リソースマネージャ接続ファクトリへの参照
ファクトリは、他のオブジェクトを随時作成するオブジェクトです。リソースファクトリは、データベース接続やメッセージサービス接続などのリソースオブジェクトを作成します。これは、標準配備記述子の <resource-ref> 要素を使って設定されます。
次の例では、ファクトリの使用について説明しています。
例 A
タイプが javax.sql.DataSource のオブジェクトを返す JDBC 接続ファクトリへの参照の宣言は次のとおりです。
<resource-ref>
<description> Primary database </description>
<res-ref-name> jdbc/primaryDB </res-ref-name>
<res-type> javax.sql.DataSource </res-type>
<res-auth>Container</res-auth>
</resource-ref>例 B
JavaMail Session リソースファクトリへの参照の例は次のとおりです。
<resource-ref>
<description> mail Session </description>
<res-ref-name> mail/Session </res-ref-name>
<res-type> javax.mail.Session </res-type>
<res-auth>Container</res-auth>
</resource-ref><res-type> は、リソースファクトリの完全修飾クラス名です。<res-auth> 変数には、コンテナまたはアプリケーションを値として指定できます。Java Mail セッションリソースファクトリの詳細については、「JavaMail リソースについて」を参照してください。
コンテナを指定すると、リソースファクトリを JNDI ルックアップレジストリに結びつける前に、Web コンテナが認証を処理します。アプリケーションを指定した場合は、サーブレットが認証をプログラム的に処理する必要があります。次のように、リソースファクトリが異なると、リソースタイプを説明する異なるサブコンテキストがルックアップ対象となります。
- JDBC の javax.sql.DataSource ファクトリの場合は、jdbc/
- JMS の javax.jms.QueueConnectionFactory ファクトリまたは javax.jms.TopicConnectionFactory ファクトリの場合は、jms/
- JavaMail の JavaMail javax.mail.Session factory ファクトリの場合は、mail/
- java.net.URL factory ファクトリの場合は、url/
コンテナが認証を処理するアプリケーションコンポーネントからの JDBC 接続を取得するコード例は、次のとおりです。
InitialContext initContext = new InitialContext();
DataSource source =
(DataSource) initContext.lookup("java:comp/env/jdbc/primaryDB");
Connection conn = source.getConnection();これらのリソース参照が正しく機能するには、実行時に res-ref-name を有効なリソースファクトリにマップする必要があります。
リソース環境参照
リソース環境参照を使うことで、リソースに関連づけられた管理対象オブジェクトに JNDI ルックアップを通じてアクセスできます。たとえば、アプリケーションが JMS 送信先オブジェクトにアクセスする場合などです。アプリケーションは、標準の配備記述子に定義される <resource-env-ref> 要素を使ってリソースの要件を宣言できます。
<resource-env-ref> 要素と <resource-ref> 要素の主な違いは、特定のリソース認証要件の有無です。どちらの要素もリソースファクトリ記述子によるバックアップが必要です。
例
<resource-env-ref>
<description> My Topic </description>
<res-env-ref-name> jms/MyTopic </res-ref-name>
<res-env-ref-type> javax.jms.Topic </res-type>
</resource-env-ref>次のコード例は、JMS Topic オブジェクトへのアクセスを許可します。
InitialContext initContext = new InitialContext();
javax.jms.Topic myTopic =
(javax.jms.Topic) initContext.lookup("java:comp/env/jms/MyTopic");resource-env-ref 変数が正しく機能するためには、管理者は実行時にターゲットリソースファクトリを利用できるように設定する必要があります。JMS Topic と Queue 送信先へのアクセスについては、「JMS サービスの使用」を参照してください。
UserTransaction 参照
J2EE では、コンテナが JNDI 名 java:comp/UserTransaction に UserTransaction オブジェクトの実装を提供する必要があります。アプリケーションは、UserTransaction オブジェクトを使ってトランザクションを開始、コミット、中止します。
トランザクションをプログラム的に初期化、実行する場合、コンポーネントは java:comp/UserTransaction のJNDI ルックアップを実行してコンテナのデフォルトトランザクションコーディネータへの参照を取得します。返されるオブジェクトは、javax.transaction.UserTransaction インタフェースを実装しており、トランザクションを開始、コミット、ロールバックし、トランザクションの状態を問い合わせるプログラムで使用できます。Sun ONE Application Serverに実装される JNDI は、このようなトランザクションコーディネータのルックアップをサポートしています。javax.transaction.UserTransaction インタフェースの詳細については、「トランザクションサービスの使用」を参照してください。
初期ネーミングコンテキスト
Sun ONE Application Server がサポートするネーミングは、J2EE 1.3 を基本として、いくつかの拡張が追加されています。アプリケーションコンポーネントが InitialContext() を使って初期コンテキストを作成すると、Sun ONE Application Server はアプリケーションのネーミング環境への参照として機能するオブジェクトを返します。次に、このオブジェクトは java:comp/env namespace のサブコンテキストを返します。各アプリケーションには専用の名前スペースがあります。つまり、java:comp/env name スペースはアプリケーションごとに存在し、あるアプリケーションの名前スペースに結びつけられるオブジェクトは、別のアプリケーションに結びつけられるオブジェクトと競合しません。
COSNaming サービス
Enterprise JavaBean 相互運用プロトコルでは、JNDI API を使った Enterprise JavaBean オブジェクトのルックアップに COSNaming プロトコルを使う必要があります。
Enterprise JavaBean コンテナは、CORBA CosNaming サービスに EJBHome オブジェクト参照をパブリッシュできる必要があります。CosNaming サービスは、定義されている CosNaming モジュールに IDL インタフェースを実装し、IIOP を通じたオペレーションをクライアントが解決および一覧できるようにする必要があります。
CosNaming サービスは、ルート NamingContext オブジェクトのホスト、ポート、およびオブジェクトキーを提供する上で、CORBA Interoperable Name Service 仕様の要件に従う必要があります。CosNaming サービスは、指定されたホスト、ポート、およびオブジェクトキーのルート NamingContext で IIOP を呼び出す必要があります。
クライアントコンテナ (Enterprise JavaBean、Web、またはアプリケーションクライアントコンテナ) には、サーバーの CosNaming サービスにアクセスし、標準の CosNaming API を使って EJBHome オブジェクトを解決するために、Interoperable Name Service 仕様に定義されているメカニズムを使う JNDI CosNaming サービスプロバイダが含まれている必要があります。JNDI CosNaming サービスプロバイダが、JNDI SPI アーキテクチャを使っているとは限りません。JNDI CosNaming サービスプロバイダは、次の URL からオブジェクト参照を作成し、サーバーの CosNaming サービスのルート NamingContext にアクセスする必要があります。
corbaloc:iiop:1.2@<host>:<port>/<objectkey> の <host>、<port>、および <objectkey> は、サーバーの CosNaming サービスによって指定されるルート NamingContext に対応する値です。この URL または同等のメカニズムを使用する必要があります。
配備時に、クライアントコンテナの開発者は、サーバーの CosNaming サービスのホスト、ポート、およびオブジェクトキー、およびクライアントコンポーネントの配備記述子に含まれる各 ejb-ref 要素について、サーバーの名前スペースを参照するなどして、サーバーの EJBHome オブジェクトの CosNaming 名を取得する必要があります。次に、ejb-ref-name (これは JNDI ルックアップの呼び出しでクライアントコードによって使用される) を EJBHome オブジェクトの CosNaming 名にリンクします。実行時は、クライアントコンポーネントの JNDI ルックアップ呼び出しは、サーバーの CosNaming サービスにアクセスする CosNaming サービスプロバイダを使って CosNaming 名を解決し、クライアントコンポーネントに EJBHome オブジェクト参照を返します。
EJBHome オブジェクトの名前は、指定されたホストとポートでアクセスが可能な CosNaming サービスの名前スペースに確実に存在するため、クライアントコンテナとサーバーコンテナの名前スペースを組み合わせる必要はありません。
CosNaming を使う利点は、非 J2EE CORBA クライアントおよびサーバーとの相互運用で必要となる IIOP インフラストラクチャとの統合性が高いことです。CosNaming は CORBA オブジェクトだけを格納するため、多くのベンダーは、その他のリソースを格納するために別のエンタープライズディレクトリサービスも使用します。
Sun ONE Application Server は、J2EE 1.3 仕様に基づいて、JNDI のすべてのネーミングリソースを統合します。
CosNaming プロバイダグローバルな JNDI 名スペースをサポートする (IIOP アプリケーションクライアントにアクセスできる) ために、Sun ONE Application Server には J2EE ベースの CosNaming プロバイダが含まれます。このプロバイダは、CORBA 参照 (リモート EJB 参照) のバインドをサポートします。IIOP クライアントに返される InitialContext は CosNaming プロバイダです。Sun ONE Application Serverのインスタンスは、IIOP クライアントがルックアップし、バインドするエンティティ Beans を登録します。
Sun ONE Application Server は、CosNaming およびローカル JNDI ネーミング環境に格納されるオブジェクトを一時的なものとして扱います。つまり、サーバーの起動時またはアプリケーションの再読み込み時に、すべての関連オブジェクトは元の名前スペースに戻されます。CORBA/IIOP クライアントの設定については、「Corba/IIOP クライアント用のサーバーの設定」を参照してください。
JNDI 接続ファクトリ
J2EE Web アプリケーションでは、web.xml ファイル内の配備記述子を使って、アプリケーション環境エントリ、リソースマネージャ (SQL データソースなど) 接続ファクトリ、または Enterprise JavaBean への参照を定義します。アプリケーションは、J2EE コンテナから提供される JNDI InitialNamingContext を使ってこれらの参照をルックアップします。これにより、アプリケーションのソースコードにアクセスしたり、変更したりせずに、配備記述子に変更を加えるだけで別のアプリケーションサーバー環境にアプリケーションを移植できます。同様に、J2EE では、これらの JNDI ネーミング参照の主要な連絡媒体として、エンティティ Beans の配備記述子 (ejb-jar.xml) や IIOP アプリケーションクライアントの配備記述子 (application-client.xml) が必要となります。
コネクションファクトリは、J2EE コンポーネントによるリソースへのアクセスを可能にするコネクションオブジェクトを作成するオブジェクトです。データベースの接続ファクトリは javax.sql.DataSource オブジェクトで、このオブジェクトは java.sql.Connection オブジェクトを作成します。
Sun ONE Application Server では、次のリソースとリソースファクトリにアクセスする方法を設定できます。
- JDBC 接続ファクトリ
- MQ に基づく JMS 接続ファクトリ
- JavaMail セッション接続ファクトリ
- JCA 接続ファクトリ
- ユーザーが記述する汎用のカスタムリソースオブジェクトファクトリ
- LDAP などの外部リソースリポジトリのサポート
すべての Sun ONE Application Server リソースファクトリは、server.xml ファイルの <resources> </resources> タグ内に指定され、jndi-name 属性を使って指定される JNDI 名を持ちます。この属性は、ファクトリをサーバー全体の名前スペースに登録するときに使われます。開発者は、ユーザーが指定したアプリケーション固有のリソース参照名 (resource-ref 要素または resource-env-ref 要素内で宣言される) を、resource-ref-mapping 要素を使ってサーバー全体のリソースファクトリにマッピングできます。これにより、特定のアプリケーションにどの JDBC ドライバ (およびその他のリソースファクトリ) を使うかを配備時に決定できます。
カスタムリソースはローカル JNDI リポジトリにアクセスし、外部リソースは外部 JNDI リポジトリにアクセスします。どちらのリソースも、ユーザーが指定したファクトリクラス要素、JNDI 名、属性などを必要とします。ここでは、JNDI 接続ファクトリリソースを J2EE リソース用に設定する方法と、これらのリソースにアクセスする方法について説明します。
この節では次の項目について説明します。
- カスタムリソースの作成
- 外部 JNDI リソースの作成
- 外部 JNDI リポジトリへのアクセス
- アプリケーションリソース参照のマッピング
- URL 接続ファクトリリソースについて
- アプリケーションリソース環境参照のマッピング
- EJB 参照のマッピング
カスタムリソースの作成
サーバー全体のカスタムリソースオブジェクトファクトリを指定するときは、server.xml に定義されている custom-resource 要素を使います。これらのオブジェクトファクトリは、javax.naming.spi.ObjectFactory インタフェースを実装しています。この要素は、サーバー全体の名前スペースで使われる JNDI 名 (その他の Sun ONE Application Server リソースのように、jndi-name サブ要素を使って指定される) と、タイプ、リソースファクトリクラスの名前、インスタンス化で使われる標準プロパティのセットを関連づけます。
次の例は、javax.naming.spi.ObjectFactory インタフェースの実装を示しています。
<resources> <custom-resource jndi-name="test/myBean"
res-type="test.MyBean"factory-class="test.MyBeanFactory"
enabled="true"><property name="foo" value="test custom bean prop" />
</custom-resource>
</resources>リソース参照の環境参照と EJB 参照は、server.xml 内の custom-resource タグと external-jndi-resource タグを使って定義されるサーバー全体の設定済みリソースにリンクされている必要があります。アプリケーションコンポーネントの動的な再配備は、JNDI ネーミング環境の問題です。Sun ONE Application Server は、アプリケーション固有のすべての参照を解放し、すべての新しい参照を新たにインストールされたアプリケーションのネーミングコンテキストに結びつけます。
管理インタフェースを使ってカスタムリソースを作成するには、次の手順を実行します。
- Sun ONE Application Serverの左側のペインで、変更したい JNDI 設定を含むアプリケーションサーバーインスタンスを開きます。
- 「JNDI」を展開し、「カスタムリソース」をクリックします。すでにカスタムリソースが作成されている場合は、右側のペインにそれがリスト表示されます。新しいカスタムリソースを作成するには、「新規」をクリックします。管理インタフェースの右側のペインに「JNDI のカスタムリソースページ」が表示されます。
   JNDI のカスタムリソースページ
- リソースへのアクセスに使う名前を「JNDI 名」フィールドに入力します。この名前は JNDI ネーミングサービスに登録されます。
- 上記の例のように、タイプの完全修飾定義を「リソースタイプ」に入力します。リソースタイプの定義は、次の形式で指定する必要があります。xxx.xxx.
- 作成しているカスタムリソースのファクトリクラス名を「ファクトリクラス」フィールドに入力します。この名前は、ユーザーが指定するファクトリクラス名です。このクラスは、javax.naming.spi.ObjectFactory インタフェースを実装します。
- 作成しているリソースの説明を「説明」フィールドに入力します。これは文字列のフィールドです。250 文字以内で入力します。
- 「カスタムリソースを有効」ボックスにチェックマークをつけて、カスタムリソースを有効にします。
- 「了解」をクリックして、外部リソースを保存します。
外部 JNDI リソースの作成
管理インタフェースを使って外部リソースを作成するには、次の手順を実行します。
- Sun ONE Application Serverの左側のペインで、変更したい JNDI 設定を含むSun ONE Application Serverインスタンスを開きます。
- 「JNDI」を開き、「外部リソース」を選択します。すでに外部リソースが作成されている場合は、右側のペインにそれがリスト表示されます。新しい外部リソースを作成するには、「新規」をクリックします。
管理インタフェースの右側のペインに次のような「JNDI 外部ソースページ」のウィンドウが表示されます。
   JNDI 外部ソースページ
- リソースへのアクセスに使う名前を「JNDI 名」フィールドに入力します。この名前は JNDI ネーミングサービスに登録されます。
- 上記の例のように、タイプの完全修飾定義を「リソースタイプ」に入力します。リソースタイプの定義は、次の形式で指定する必要があります。xxx.xxx.
- 外部リポジトリでルックアップする JNDI 値を「JNDI ルックアップ」に入力します。たとえば、Bean クラスをテストするために外部リポジトリに接続する外部リソースを作成する場合は、JNDI 値は cn=testmybean となります。
- たとえば com.sun.jndi.ldap のような JNDI ファクトリクラス外部リポジトリを「ファクトリクラス」フィールドに入力します。このクラスは、javax.naming.spi.ObjectFactory インタフェースを実装します。
- 作成しているリソースの説明を「説明」フィールドに入力します。これは文字列のフィールドです。250 文字以内で入力します。
- 「外部リソースを有効」ボックスにチェックマークをつけて、外部リソースを有効にします。
- 「了解」をクリックして、外部リソースを保存します。
外部 JNDI リポジトリへのアクセス
Sun ONE Application Server で稼働するアプリケーションの多くは、外部 JNDI リポジトリに格納されているリソースにアクセスします。たとえば、汎用の Java オブジェクトは、Java スキーマごとに LDAP に格納されます。外部 JNDI リソース要素を使うことで、このような外部リソースリポジトリを設定できます。外部 JNDI ファクトリは、javax.naming.spi.InitialContextFactory インタフェースを実装する必要があります。
例
<resources>
<!-- external-jndi-resource 要素は、外部 JNDI リポジトリに格納されて
-- いる J2EE リソースへのアクセス方法を指定します。次の例は、LDAP に
-- 格納されている Java オブジェクトへのアクセス方法を示しています。
-- factory-class 要素は、リソースファクトリへのアクセスに必要な JNDI
-- InitialContext ファクトリを指定します。外部 JNDI コンテキストおよび
-- jndi-lookup-name に適用される環境に対応するプロパティ要素は、JNDI
-- 名を参照してルックアップし、ターゲットオブジェクト (この場合は Java)
-- を取得します。
-->
<external-jndi-resource jndi-name="test/myBean"
jndi-lookup-name="cn=myBean"
res-type="test.myBean"
factory-class="com.sun.jndi.ldap.LdapCtxFactory"><property name="PROVIDER-URL" value="ldap://ldapserver:389/o=myObjects" />
<property name="SECURITY_AUTHENTICATION" value="simple" />
<property name="SECURITY_PRINCIPAL", value="cn=joeSmith, o=Engineering" />
<property name="SECURITY_CREDENTIALS" value="changeit" />
</external-jndi-resource>
</resources>アプリケーションリソース参照のマッピング
アプリケーション固有のリソース参照は、事前に定義されたサーバー全体のリソースファクトリにマップする必要があります。このマップには、Sun ONE Application Server 固有のリソース参照をマップする要素が使われます。
次の例では、リソース参照が JDBC DataSource に指定されている Web アプリケーションの配備記述子 web.xml を紹介します。
<resource-ref>
<res-ref-name> jdbc/EstoreDataSource </res-ref-name>
<res-type> javax.sql.DataSource </res-type>
<res-auth>Container</res-auth>
</resource-ref>次のように、目的の res-ref-name をコンテナ全体の Oracle JDBC 接続リソースファクトリにマップすることもできます。
<resource-ref>
<res-ref-name> jdbc/EstoreDataSource </resource-ref-name>
<jndi-name> jdbc/estore/InventoryDB </jndi-name>
</resource-ref>URL 接続ファクトリリソースについて
URL 接続ファクトリでは、server.xml にリソースを定義する必要はありません。Sun ONE Application Server アプリケーションの Web または Enterprise JavaBean 配備記述子に対応する jndi-name 要素がターゲット URL を決定します。
たとえば、Web アプリケーションの配備記述子 web.xml がリソース参照 java.net.URL を指定し、これが sun-web.xml 内の URL http://www.sun.com/index.html にマップされていると仮定します。
マッピングは次のようになります。
<resource-ref>
<res-ref-name>myURL</res-ref-name>
<res-type>java.net.URL</res-type>
<res-auth>Container</res-auth>
</resource-ref><sun-web-app>
<resource-ref>
<res-ref-name>myURL</res-ref-name>
<jndi-name> http://www.sun.com/index.html </jndi-name>
</resource-ref>
</sun-web-app>アプリケーションリソース環境参照のマッピング
アプリケーション固有のリソース環境参照宣言は、アプリケーションサーバーの実行時環境で利用できるターゲットリソースオブジェクトにマップする必要があります。配備担当者は、次のように Sun ONE Application Server 固有の設定ファイルに定義されるリソース環境マッピング要素を使うことで、このマッピングを行えます。
例
<resource-env-ref>
<description> My Topic </description>
<res-env-ref-name> jms/MyTopic </res-ref-name>
<res-env-ref-type> javax.jms.Topic </res-type>
</resource-env-ref>この参照は、server.xml に定義されている jms/iMQ/Topics/Stocks/SUNW トピックにマップされます。詳細は、『Sun ONE Application Server 管理者用設定ファイルリファレンス』を参照してください。
<resource-env-ref-mapping>
<res-env-ref-name> jms/MyTopic </res-ref-name>
<jndi-name> jms/iMQ/Topics/Stocks/SUNW </jndi-name>
</resource-env-ref-mapping>EJB 参照のマッピング
アプリケーションコードで実際に使われている ejb-name をターゲット Enterprise JavaBean で使われている ejb-name から切り離すこともできます。これは、Web アプリケーションの配備記述子 web.xml を変更せずに、Enterprise JavaBean の配備記述子の ejb-name を使う場合に特に便利です。固有の設定を使うことで、Sun ONE Application Server 固有の配備記述子に含まれる ejb-ref-mapping 要素を使わずに、ejb-ref-name 要素をターゲット Bean の ejb-name にマップできます。
例
<ejb-ref>
<ejb-ref-name> ejb/EmplRecord </ejb-ref-name>
<ejb-ref-type> Entity </ejb-ref-type>
<home> com.wombat.empl.EmployeeRecordHome </home>
<remote> com.wombat.empl.EmployeeRecord </remote>
</ejb-ref><ejb-ref>
<ejb-ref-name> ejb/EmplRecord </ejb-ref-name>
<jndi-name> AccountEJB </jndi-name>
</ejb-ref-mapping>持続マネージャリソースについて
この節では、持続性について、および Sun ONE Application Server がサポートしているプラグイン可能な持続マネージャの概要について説明します。
この節では、次の項目について説明します。
持続性について
ほとんどのビジネスアプリケーションで重要とされるのは、アプリケーション外に長期間格納される持続性データのプログラム処理です。使用や変更が必要な場合は、持続性データは一時メモリに読み込まれますが、長期的に保管する場合は、データはリレーショナルデータベースや単層ファイルシステムに書き込まれます。
オブジェクト指向のプログラミングシステムでは、アプリケーションコードが 1 つまたは複数のオブジェクトを操作すると、持続性データはメモリに読み込まれます。次の図「基本的な持続性スキーム」に示すように、一般に、データストア内の持続性データとメモリ内の持続性データオブジェクトは、何層ものソフトウェア層を介して対応しています。
   基本的な持続性スキーム
各データストアには、データストアとアプリケーションの接続を設定、維持するドライバソフトウェアを介して外界に通じるインタフェースがあります。この接続が確立されている状態では、データストアからの情報の取得、アプリケーションへの情報の読み込み、あるいはその反対にアプリケーションからデータストアへのデータの書き込みにはクエリ言語が使われます。もう一方の層は、メモリ内のデータオブジェクトとデータストア上の情報とのマップを行います。
この一般スキームでは、プログラマはアプリケーションが使用、操作する実行時オブジェクトとして持続性データを扱えます。このスキームは、基本的なすべての持続操作 (CRUD と呼ばれます) をサポートしています。
- C (Creating) - 持続性データの作成 (データストアへの挿入)
- R (Retrieving) - 持続性データの検索 (データストアからの選択)
- U (Updating) - 持続性データの更新
- D (Deleting) - 持続性データの削除
持続マネージャの役割
PM (持続マネージャ) は、Enterprise JavaBean コンテナ内で持続性がコンテナ管理のエンティティ Beans の持続性を維持します。エンティティ Bean のプロバイダは、エンティティ Bean のクラスを抽象クラスとして提供する必要があります。PM プロバイダのツールは、具体的な実装を提供する必要があります。これらは、抽象エンティティ Bean と関連クラスをサブクラスに分け、具体的な実装を提供したり、カプセル化と委譲を使って、持続性を維持します。
PM のツールで提供されるクラスは、エンティティ Beans 間の関係および持続状態へのアクセスを管理します。また、PM ツールは、コンテナ管理による関係 (CMR) の管理に使用される java.util.Collection クラスの実装を提供する必要があります。
配備前の Bean の設定
Enterprise JavaBean の標準には、Enterprise JavaBean の 2 種類の持続性が定義されています。コンテナ管理による持続性 (CMP) と Bean 管理による持続性 (BMP) がそれにあたります。Enterprise JavaBean 2.0 仕様には、Enterprise JavaBean サーバーと持続マネージャを結ぶ標準の API は定義されていません。
ここでは、配備とコード生成で必要になる統合要件について説明します。配備には複数の意味があります。一般に、配備プロセスは設定、コード生成、インストールという 3 段階の手順から構成されます。
使用する持続メカニズム、持続性ベンダー、使用中のバージョン、持続メカニズムが必要とする追加情報など、Bean には多数のプロパティを設定する必要があります。ほとんどの持続性ベンダーには、関連するすべての Bean およびその依存クラスを表し、1 つの単位として配備することができるプロジェクトという概念が適用されます。プロジェクトごとにベンダー固有の xml ファイルを利用できます。
配備に使用する標準ファイルには、ejb-jar.xml、sun-ejb-jar.xml、sun-cmp-mappings.xml の 3 種類があります。CMP Beans を持つ Enterprise JavaBean モジュールは、sun-ejb-jar.xml 内に <pm-descriptors> を持ち、ここに少なくとも 1 つの <pm-descriptor> 要素があります。さらに、この要素は 5 つの属性を指定します。この 5 つの属性は、pm-identifier、pm-version、pm-config、pm-class-generator、pm-mapping-factory です。
sunEjb_jar_2_0.DTD 内の記述子のような Sun ONE Application Server 固有の記述子は持続マネージャに関するタグを定義します。CMP 記述子の例として、Sun ONE Application Server DTD に定義されている次のようなコードを示します。
PM 記述子には 1 つまたは複数の pm 記述子を含めることができます。ただし一度に使える記述子は 1 つだけです。
-->
<!ELEMENT pm-descriptors ( pm-descriptor+, pm-inuse)>
<!--
pm-descriptor は、エンティティ Bean に関連付けられた持続マネージャの
プロパティを示します。
-->
<!ELEMENT pm-descriptor ( pm-identifier, pm-version, pm-config?, pm-class-generator?,
pm-mapping-factory?)>
<!--
この要素は、PM の実装を提供するベンダーを説明しています。この例では、Sun ONE Application Server Transparent Persistence、TopLink、Versant、または CocoBase となります
-->
<!ELEMENT pm-identifier (#PCDATA)>
<!--
pm-version は、使用する PM ベンダー製品のバージョンを指定します
-->
<!ELEMENT pm-version (#PCDATA)>
<!--
pm-config は、使用するベンダー固有の設定ファイルを指定します
-->
<!ELEMENT pm-config (#PCDATA)>
<!--
pm-class-generator は、ベンダー固有の具体的なクラスのジェネレータを指定します
これは、そのベンダーに固有のクラスの名前です
-->
<!ELEMENT pm-class-generator (#PCDATA)>
<!--
pm-mapping-factory は、ベンダー固有のマッピングファクトリを指定します
これは、そのベンダーに固有のクラスの名前です
-->
<!ELEMENT pm-mapping-factory (#PCDATA)>
持続マネージャの新規作成
管理インタフェースを使って新しい持続マネージャを作成できます。持続マネージャを新規作成するには、次の手順を実行します。
- 管理インタフェースの左側のペインで、新たに持続マネージャを作成するSun ONE Application Serverインスタンスを開きます。表示されるサーバーコンポーネントのリストから「持続マネージャ」を選択します。
そのSun ONE Application Serverインスタンスに固有の持続マネージャがすでに作成されている場合は、管理インタフェースの右側のペインにリスト表示されます。
- 新しい持続マネージャを作成するには、「新規」をクリックします。以下のような「持続マネージャの新規作成」用のウィンドウが表示されます。
   持続マネージャの新規作成
- アプリケーションに代わる持続マネージャを特定するためにアプリケーションサーバーランタイムが使用する JNDI 名を「JNDI 名」に入力します。この名前は、Sun ONE Application Server 固有の配備記述子に含まれるエンティティ Bean のcmp-resource 要素に定義されている名前と同じである必要があります。
- 新しい持続マネージャの説明を「説明」フィールドに入力します。これは文字列のフィールドです。250 文字以内で入力します。
- 持続マネージャのファクトリクラス接続を「ファクトリクラス」フィールドに入力します。setEntityContext はこの接続ファクトリから JNDI 名をルックアップします。ファクトリクラス名は、持続マネージャインスタンスを作成する持続マネージャファクトリのクラス名です。標準の設定では、これは Sun ONE Application Server の内部持続マネージャファクトリクラスに設定されます。別の実装を使う場合は、サーバークラスパスからそのクラスにアクセスできる必要があります。
- 新しい持続マネージャがプールされるデータベース接続プールを「接続プール」ドロップダウンリストから選択します。接続プールでは、エンティティ Bean は 1 つの接続を要求し、それを使って複数のクライアントスレッドのステートメントを同時に実行できます。その他のデータベースアクセスと同様に、持続マネージャは接続プールを使ってパフォーマンスとスケーラビリティを向上します。既存の接続プールを選択するか、プールを作成していない場合は「何も選択されていません (何も選択されていません)」を選択します。
注 : PM ランタイムが JNDI を使って接続プールにバインドできるように、JDBC リソースが自動的に作成されます。JDBC リソースの JNDI 名は、プレフィックス「PM」をつけた PM JNDI 名と同じになります。持続マネージャを削除すると、関連する JDBC リソースも削除されます。
- 「持続マネージャを有効」ボックスにチェックマークをつけて、持続マネージャを有効にします。これで、指定した接続ファクトリの持続マネージャが有効になります。
- 「了解」をクリックして、変更内容を保存します。
JDBC リソースについて
この節では、JDBC API の概要を説明し、JDBC リソースについて、および Sun ONE Application Server での JDBC リソースの実装と使用について詳しく説明します。
この節には次の項目があります。
JDBC API について
JDBC API は、仮想的にあらゆる表形式データにアクセスするための Java API です。JDBC は「Java Database Connectivity」の略号であると考えられがちですが、これは商標名であって略号ではありません。JDBC API は Java プログラミング言語で記述されたクラスとインタフェースのセットです。これは、ツールやデータベースの開発者に標準 API を提供し、全体を Java で記述した API によるデータベースアプリケーションの作成を可能にします。
JDBC API を使うことで、リレーショナルデータベースシステムへのSQL ステートメントの送信や、あらゆる種類の SQL のサポートが簡単になります。ただし、JDBC 3.0 API はデータベース外のファイルなど、その他の種類のデータソースの利用にも対応しており、SQL だけを対象とした API ではありません。
JDBC API の利点は、アプリケーションが仮想的にあらゆるデータソースにアクセスし、Java 仮想マシンを実装したあらゆるプラットフォームで実行できることにあります。言い換えれば、JDBC API を使うことで、Sybase データベースにアクセスするプログラムを記述すると、Oracle データベースや IBM DB2 データベースなどにアクセスする別のプログラムを個別に記述する必要がなくなります。JDBC API を使って 1 つのプログラムを記述すれば、そのプログラムは SQL などのステートメントを適切なデータソースに送信できます。また、Java プログラミング言語で記述したアプリケーションを使えば、プラットフォームごとに異なるアプリケーションを記述する必要もなくなります。Java プラットフォームと JDBC API を組み合わせることで、プログラマは 1 回記述したコードをどこででも実行できます。
JDBC API の機能
JDBC テクノロジベースのドライバ (JDBC ドライバ) は、次の 3 つの処理を実行できます。
- データソースとの接続を確立する
- クエリステートメントとアップデートステートメントをデータソースに送信する
- 結果を処理する
次のコードは、この 3 段階の処理を示す簡単な例です。
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("jdbc/AcmeDB");
Connection con = ds.getConnection("myLogin", "myPassword");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (rs.next()) {
int x = rs.getInt("a");
String s = rs.getString("b");
float f = rs.getFloat("c");
}
データベースアクセスモデルについて
JDBC API は、2 層と 3 層の両方のデータベースアクセスモデルをサポートしています。Sun ONE Application Server には、より一般的な 2 層のデータベースアクセスモデルが統合されています。
この節には次の項目があります。
2 層のデータベースアクセスモデル
2 層のデータベースアクセスモデルでは、Java アプレットまたはアプリケーションは、DBMS 専用プロトコルを使ってデータソースに直接アクセスします。このアクセスモデルでは、アクセス先の特定のデータソースと対話できる JDBC ドライバが必要です。ユーザーのコマンドはデータベースまたはその他のデータソースに送信され、ステートメントの結果がユーザーに返されます。データソースは、ユーザーがネットワークを介して接続できる別のマシンにあってもかまいません。この設定をクライアント / サーバー設定と呼び、ユーザーのマシンをクライアント、データソースを格納するマシンをサーバーと呼びます。ネットワークは、企業の従業員が接続するようなイントラネットでも、インターネットでもかまいません。
3 層のデータベースアクセスモデル
3 層のデータベースアクセスモデルでは、Java アプレットまたはアプリケーションはサービスの「中間層」にコマンドを送信し、コマンドはそこからデータソースに送信されます。クライアントアプリケーションは HTTP、RM、CORBA などの呼び出しを使って中間層と対話します。中間層は、DBMS 専用プロトコルを使ってデータソースと対話します。データソースはコマンドを処理し、結果を中間層に返し、中間層は結果をユーザーに返します。中間層を設けることで、企業データへのアクセスと実行できるアップデートの種類を管理できるため、MIS のディレクターには 3 層のアクセスモデルは魅力的かもしれません。また、アプリケーションの配備が簡単になるという利点もあります。さらに、多くの場合、3 層のアーキテクチャにはパフォーマンス上の利点もあります。
JDBC データソースについて
DataSource オブジェクトは、Java プログラミング言語で記述されたデータソースです。データソースは、基本的にはデータを格納するための機能です。大企業の複雑なデータベースのように洗練されている場合もあれば、行と列だけを含む簡単なファイルである場合もあります。データソースは、リモートサーバーに置くことも、ローカルマシンに置くこともできます。アプリケーションは接続を使ってデータソースにアクセスし、DataSource インスタンスが指定する特定データソースへの接続のファクトリとして DataSource オブジェクトを使います。DataSource インタフェースには、データソースとの接続を確立する 2 種類のメソッドが用意されています。
DataSource オブジェクトには、特定のデータソースを識別および説明するプロパティがあります。また、DataSource オブジェクトと JNDI ネーミングサービスを併用することで、そのオブジェクトを使うアプリケーションとは別に作成、配備、管理することができます。ドライバベンダーは、DataSource インタフェースの基本実装となるクラスを JDBC 2.0 または 3.0 ドライバ製品の一部として提供します。
この節には次の項目があります。
DataSource オブジェクトのプロパティ
DataSource オブジェクトには、実際のデータソースを識別するプロパティセットがあります。これらのプロパティには、データベースサーバーの場所、データベースの名前、サーバーとの通信に使用するネットワークプロトコルなどの情報が含まれます。DataSource のプロパティは、JavaBeans の設計パターンを踏襲しているので、通常は DataSource オブジェクトの配備時に設定されます。
ベンダー間での DataSource 実装の均一性を確保するために、JDBC 2.0 API ではプロパティの標準セット、および各プロパティの標準名を規定しています。
DataSource インタフェースを実装するクラスのインスタンスは、1 つの特定のデータソースを表します。そのインスタンスが作成するすべての接続は、同じデータソースを参照します。DataSource の基本的な実装では、DriverManager によって返される接続オブジェクトと同様に、DataSource.getConnection メソッドの呼び出しによって、データソースとの物理的な接続を提供する接続オブジェクトが返されます。
アプリケーションがネットワーク上のリモートサービスを探してアクセスする方法は、JNDI によって提供されます。リモートサービスは、メッセージングサービスやアプリケーション固有のサービスなど、どのようなエンタープライズサービスでもかまいませんが、JDBC アプリケーションの主な目的は、もちろんデータベースサービスにあります。DataSource オブジェクトを作成して JNDI ネーミングサービスに登録すると、アプリケーションは JNDI API を使ってその DataSource オブジェクトにアクセスできるようになり、そのオブジェクトが表すデータソースへの接続に利用されます。
同様に、接続プールを実装する DataSource オブジェクトは、DataSource クラスによって表される特定のデータソースへの接続を作成します。ただし、DataSource.getConnection メソッドが返す接続オブジェクトは、物理的な接続ではなく、PooledConnection オブジェクトへの参照です。アプリケーションは、通常どおりに接続オブジェクトを使うため、違いを意識することはほとんどありません。すべての接続と同様に、プールされた接続を常に明示的に閉じることが必要であることを除き、接続プールはアプリケーションコードにまったく影響しません。プールされている接続をアプリケーションが閉じると、接続は再利用可能な接続のプールに加えられます。次に DataSource.getConnection を呼び出したときに、接続が残っていれば、プールされているいずれかの接続への参照が返されます。接続プールを利用することで、要求のたびに物理的な接続を作成する必要がなくなるため、アプリケーションを高速に実行するのに役立ちます。
同様に、分散トランザクション環境で機能するように DataSource クラスを実装することもできます。たとえば、Enterprise JavaBean サーバーは分散トランザクションをサポートしており、対話相手となる DataSource クラスの実装を必要とします。この場合、DataSource.getConnection メソッドは分散トランザクションで利用できる Connection オブジェクトを返します。規定により、Enterprise JavaBean サーバーは接続プールと分散トランザクションの両方をサポートします。トランザクション管理も、接続プールのように内部処理されるため、分散環境の利用は簡単です。ただし、トランザクションを分散するときに、アプリケーションがトランザクションメソッドとして commit または rollback を呼び出せないという制約があります。また、接続を auto-commit モードでプットすることもできません。これらの制約は、トランザクションマネージャが分散トランザクションを自動的に開始、終了するため、トランザクションの開始時または終了時に影響する処理をアプリケーションが実行できないことに起因しています。Java トランザクションの詳細については、「トランザクションサービスの使用」を参照してください。
JDBC リソースの登録
管理インタフェースまたはコマンド行インタフェースを使って、JDBC リソースを Sun ONE Application Server に登録できます。
この節には次の項目があります。
コマンド行によるリソースの登録
コマンド行インタフェースを使って JDBC リソースを登録するには、次のコマンドを実行します。
./asadmin create-jdbc-resource
次に示すように、JDBC リソースを登録する XML コードにはいくつかの属性を指定する必要があります (sun-server_7_0.dtd から抜粋)。
<!-- JDBC javax.sql.DataSource resource definition -->
<!ELEMENT jdbc-resource (description?, property*)>
<<!ATTLIST jdbc-resource jndi-name CDATA #REQUIRED
pool-name CDATA #REQUIRED
enabled %boolean; 'true'>
すべての指定は、J2EE アプリケーションの内部からアプリケーションがこのデータソースを参照するときに使われる象徴的な名前です。pool-name 属性は、名前がつけられたプールの定義を参照し、データベースとの接続に必要なすべての設定はここで指定されます。有効な属性は、管理者が一部のリソースをオフにする場合に利用できます。
管理インタフェースによるリソースの登録
管理インタフェースを使ってデータソースを登録するには、次の手順を実行します。
- 管理インタフェースの左側のペインで、JDBC リソースを登録するアプリケーションサーバーインスタンスを開きます。
- 「JDBC」を展開します。
- 「JDBC」の下の「JDBC リソース」をクリックします。
- 右側のペインの「新規」をクリックします。次のような JDBC リソースを新規作成するためのページが右側のペインに表示されます。
   JDBC リソースの新規作成
- 作成するリソースの JNDI 名を「JNDI 名」フィールドに入力します。
JDBC リソースは JNDI リポジトリに格納され、アクセスには JNDI 名を使います。JNDI 名の明示的なルートは Java:comp:env/ なので、名前にこの部分を含める必要はありません。指定する JNDI 名が jdbc/EmployeeDB_DS に近くなるように、jdbc サブコンテキストの下に JDBC リソースを格納することをお勧めします。
- 新しいデータソースのプール名を「プール名」ドロップダウンリストから選択します。このリストには、登録されているすべての接続プールが表示されます。選択したプール名は、名前がつけられたプールの定義を参照し、データベースとの接続に必要なすべての設定が指定されます。1 つのプール定義を複数の JDBC が利用することができます。JDBC 接続プールの設定については、「管理インタフェースによる JDBC 接続プールの新規作成」を参照してください。
- データソースの目的を「説明」フィールドに簡単に入力します。250 文字以内で入力する必要があります。
- 「データソースを有効」ボックスにチェックマークをつけて、データソースを有効にします。無効にするときは、マークを外します。これが有効でない限り、データソースを使ってデータベースに接続することはできません。
- 「了解」をクリックして新しいデータソースを登録するか、「キャンセル」をクリックして新しいデータソースをキャンセルします。「キャンセル」をクリックすると、JDBC リソースのメインページに戻ります。新しいデータソースの作成は、このページから再開できます。
JDBC 接続について
接続オブジェクトはデータベースとの接続を表します。接続セッションには、実行される SQL ステートメント、およびその接続を介して返される結果が含まれます。1 つのアプリケーションは、1 つのデータベースとの間に 1 つまたは複数の接続を持つことも、複数の異なるデータベースとの間に複数の接続を持つこともできます。
ユーザーは Connection.getMetaData メソッドを呼び出して、接続オブジェクトのデータベースの情報を取得できます。このメソッドは、データベースの表、サポートしている SQL 文法、ストアドプロシージャ、接続の機能などの情報を含む DatabaseMetaData オブジェクトを返します。
アプリケーションは、DataSource オブジェクトが生成する接続オブジェクトを使います。例外がスローされた場合でも接続が確実に閉じるように、アプリケーションには常に「finally (最終)」ブロックが含まれている必要があります。プールされた接続が接続オブジェクトである場合は、有効な接続は常に利用可能な接続のプールに戻されるため、これは特に重要になります。次のコードは、接続が有効な場合に接続を閉じる最終ブロックの例です。con が接続オブジェクトです。
finally{
if (con != null) con.close();
}
次の例に示すように、finally ブロックは try ブロックと catch ブロックの後に記述されます。ds は DataSource オブジェクトです。
try {
Connection con = ds.getConnection("user", "secret");
// . . . アプリケーションの処理を実行するコード
} catch {
// . . . SQLException を処理するコード
} finally {
if (con != null) con.close();
}
この節には次の項目があります。
JDBC URL について
URL (Uniform Resource Locator) は、インターネット上のリソースを特定するための情報を提供します。これをアドレスと見なすこともできます。
JDBC URL は、適切なドライバがデータソースを認識し、接続を確立できるように、データソースを識別します。ドライバの開発者は、特定のドライバを識別する JDBC URL を実際に決定します。ユーザーは、JDBC URL の形式を気にする必要はなく、使用するドライバと共に供給された URL を使用するだけです。JDBC の役割は、JDBC URL の構造に適用される規約をドライバ開発者に伝えることです。
JDBC URL はさまざまなドライバで使われるため、構造に関する規約もとても柔軟です。まず、各種のドライバが異なるスキームを使ってデータベースに名前をつけることができます。たとえば、ODBC サブプロトコルでは、属性値を含む URL を作成できます (必須ではありません)。
次に、JDBC URL では、ドライバの開発者は必要なすべての接続情報をドライバにエンコードすることができます。たとえば、ユーザーがシステム管理タスクを実行することなく、指定のデータベースと会話するアプレットがデータベース接続を開くようにすることができます。
第三に、JDBC URL は間接レベルに対応しています。つまり JDBC URL は、ネットワークネーミングシステムによって実際の名前に動的に変換される論理ホスト名またはデータベース名を参照できます。これにより、システム管理者は JDBC 名の一部に特定のホストを指定する必要がなくなります。ネットワークネーミングシステムは多様であり、どれを使用するかについて制約はありません。
JDBC URL の標準的な構文は次のとおりです。3 つの部分から構成され、それぞれはコロンで区切られています。
jdbc:<subprotocol>:<subname>
JDBC URL の 3 つの部分の内容は、次のとおりです。
- jdbc プロトコル
JDBC URL のプロトコルは、常に jdbc です。
- <subprotocol>
1 つまたは複数のドライバがサポートするデータベース接続メカニズムのドライバ名またはデータベース名です。代表的なサブプロトコルに ODBC があります。これは、ODBC スタイルのデータソース名を指定する URL 用に予約されています。たとえば、JDBC-ODBC ブリッジを経由してデータベースにアクセスするには、jdbc:odbc:fred. のような URL を使用します。
この例では、サブプロトコルは ODBC で、ローカル ODBC データソース (サブネーム) は fred です。
ネットワークネーミングサービスを利用して、JDBC URL に実際のデータベース名を指定しない場合は、ネーミングサービスがサブプロトコルとなります。たとえば、次のような URL が例としてあげられます。
jdbc:dcenaming:accounts-payable
この例では、URL はローカル DCE ネーミングサービスが指定されており、このサービスは、実際のデータベースとの接続に利用できるように、accounts-payable というデータベース名をより具体的な名前に解決します。
- <subname>:
データソースを識別します。サブネームはサブプロトコルによって異なり、ドライバ開発者が選ぶ任意の内部構文を持つことができます。これには sub-subname も含まれます。subname で重要なことは、データソースを特定するのに十分な情報を持たせることです。前述の例では、残りの情報が ODBC から提供されるため、fred で十分です。ただし、リモートサーバー上のデータソースを特定するには、より多くの情報が必要となります。たとえば、インターネットを介してデータソースにアクセスする場合、次の標準 URL 命名規約に準拠して、subname の一部としてネットワークアドレスを JDBC URL に指定する必要があります。
//hostname:port/subsubname
インターネット上のホストに接続するためのプロトコルを dbnet とした場合、JDBC URL は次のようになります。
jdbc:dbnet://wombat:356/fred
JDBC 接続プールの設定
Sun ONE Application Server では、名前をつけた JDBC 接続プールを作成できます。JDBC 接続プールは、接続プールの作成に適用されるプロパティを定義します。プールの定義には名前がつけられ、複数の JDBC リソースの設定にこの定義を何度も利用できます。名前をつけたプール定義は、それぞれがサーバー起動時に物理的なプールをインスタンス化します。複数の JDBC リソースが同じプール定義を参照する場合、それぞれが実行時に同じ接続プールを利用します。
次の各項で説明するように、管理インタフェースまたはコマンド行インタフェースを使って JDBC 接続プールを作成、設定できます。
管理インタフェースによる JDBC 接続プールの新規作成
管理インタフェースを使って新しい JDBC 接続プールを作成するには、次の手順を実行します。
- 管理インタフェースの左側のペインで、新たに JDBC 接続プールを作成するSun ONE Application Serverインスタンスを開きます。
- Sun ONE Application Serverの下にリスト表示される J2EE サービスから JDBC を選択し、その下の「接続プール」タブを開きます。管理インタフェースの右側のペインに「JDBC 接続プールの新規作成」のページが表示されます。
   JDBC 接続プールの新規作成
- 作成する接続プールの JNDI 名を「名前」フィールドに入力します。
- 「グローバルトランザクションのサポート」ボックスにチェックマークをつけて、新しい接続プールのグローバルトランザクションサポートを有効にします。グローバルトランザクションに関与できる接続プールを XA 対応接続プールと呼びます。
- 「データベースベンダー」ドロップダウンリストからデータベースベンダーを選択し、「新規」をクリックします。表示される次の画面で接続プールを設定する必要があります。
接続プールの設定
接続プールを設定するには、「管理インタフェースによる JDBC 接続プールの新規作成」の手順 1 〜手順 5 までを実行します。手順 5で「新規 (New)」をクリックすると、管理インタフェースの右側のペインに新しいページが表示されます。このページには次の項目があります。
- 一般
- プロパティ
- プール設定
- 接続検証
- トランザクション遮断
このページの「一般」セクションでは、次の表に示すガイドラインに基づいてパラメータの値を指定します。
   一般設定
パラメータ
説明
属性名
接続プールの名前
データソースクラス名
DataSource API、XADataSource API、あるいはその両方を実装するベンダー固有のクラス名
説明
接続プールの説明
このページの「プロパティ」セクションでは、標準または固有の JDBC 接続プロパティを指定します。多くのプロパティは指定が必須ではありません。デフォルトでは、すべての標準プロパティの名称が表示されます。どの標準プロパティ、およびどのベンダー固有プロパティの指定が必要であるかを確認するには、データベースベンダーが提供するマニュアル等の資料を参照してください。
このページの「プール設定」セクションでは、次の表に示すガイドラインに基づいてパラメータの値を指定します。
このページの「接続検証」セクションと「トランザクション遮断」セクションでは、次の表に示すガイドラインに基づいて接続プールの検証方法とトランザクション遮断方法を指定します。
コマンド行インタフェースによる JDBC 接続プールの新規作成
ここでは、コマンド行インタフェースによる JDBC 接続プールの新規作成について、例を使って説明します。
次の表は、サーバー名やパスワードなど、接続プールの作成に必要なすべてのオプションを示しています。また、値の例も示しています。この項で説明するコマンドを実行する前に、Sun ONE Application Server のインストールに固有のパラメータを手元に準備しておくことをお勧めします。
次の例は、表「コマンド行インタフェースによる JDBC 接続プールの新規作成に必要なオプション」に示した変数の用例です。
例 1
この例は、 SampleJdbcConnectionPool という JDBC 接続プールを作成します。次のように、この例では 2 段階の処理で JDBC 接続プールを作成しています。
第 1 段階 - 接続プールの作成
JDBC 接続プールを作成するためのコマンド行インタフェースの構文は、次のとおりです。
asadmin create-jdbc-connection-pool --user admin_user [--password admin_password] [--host localhost] [--port 4848] [--secure | -s] [--instance instancename] --datasourceclassname classname [--restype res_type] [--steadypoolsize 8] [--maxpoolsize 32] [--maxwait 60000] [--poolresize 2] [--idletimeout 300] [--isolationlevel isolation_level] [--isisolationguaranteed] [--isconnectvalidatereq=false] [--validationmethod auto-commit] [--validationtable tablename] [--failconnection=false] [--description text] [--property (name=value)[:name=value]*] connectionpool_id
たとえば、次のコマンドは SampleJdbcConnectionPool という接続プールを作成します。
asadmin create-jdbc-connection-pool --user admin --password adminadmin --host sas.sun.com --port 8888 --instance server1 --restype javax.sql.XADataSource --datasourceclassname oracle.jdbc.xa.client.OracleXADataSource --description "Sample Jdbc Connection Pool" --property User="oracle":Password="oracle":URL="jdbc¥:oracle¥:thin¥:@oracleserv er.sun.com¥:1521¥:ORA" SampleJdbcConnectionPool
注 新しい接続プールの「グローバルトランザクションサポート」を有効にするときは、--restype javax.sql.XADataSource を設定します。URL プロパティのコロン (:) を (¥:) に置き換えます。
JDBC 接続プールの作成が完了すると、次のメッセージが表示されます。
Created the JDBC connection pool resource with id = SampleJdbcConnectionPool
第 2 段階 - インスタンスへの変更の適用
これで JDBC 接続プールを作成できました。次に、変更を Sun ONE Application Server の現在のインスタンスに適用する必要があります。
Sun ONE Application Server のインスタンスに変更を適用する構文は、次のとおりです。
asadmin reconfig --user admin_user [--password admin_password] [--host localhost] [--port adminport] [--secure | -s] [--discardmanualchanges=false|--keepmanualchanges=false] instancename
たとえば、次のコマンドは Sun ONE Application Server のインスタンス server1 に変更を適用します。
asadmin reconfig --user admin --password adminadmin --host sas.sun.com --port 8888 server1
Sun ONE Application Server のインスタンスに変更が適用されると、次のメッセージが表示されます。
Successfully reconfigured
コマンド行インタフェースによる JDBC 接続プールの管理
この項で説明するように、コマンド行インタフェースを使って JDBC 接続プールとそのプロパティを管理できます。
接続プールのリスト表示: 次のコマンドは、第 2 段階で使用した Sun ONE Application Server のインスタンス server1 に作成されているすべての接続プールをリスト表示します。
asadmin list-jdbc-connection-pools --user admin --password adminadmin --host sas.sun.com --port 8888 server1
JDBC 接続プールのプロパティの変更: maxPoolSize など、JDBC 接続プールのプロパティを次のような手順で変更できます。
- 次のコマンドを実行し、JDBC 接続プールの属性 maxPoolSize に指定されている値を取得します。
asadmin get -u admin -w adminadmin -H sas.sun.com -p 8888 server1.jdbc-connection-pool.SampleJdbcConnectionPool.maxPoolSize
このコマンドを実行すると、次の結果が表示されます。
server1.jdbc-connection-pool.SampleJdbcConnectionPool.maxPoolSize = 32
次のコマンドを実行し、MaxPoolSize の値を 80 に変更します。
asadmin set -u admin -w adminadmin -H sas.sun.com -p 8888 server1.jdbc-connection-pool.SampleJdbcConnectionPool.maxPoolSize="80"
値の設定が完了すると、次のメッセージが表示されます。
Attribute maxPoolSize set to 80
- 次のコマンドを実行して、Sun ONE Application Server のインスタンスに変更を適用します。
asadmin reconfig --user admin --password adminadmin --host sas.sun.com --port 8888 server1
User プロパティの変更: 次のコード例は、User プロパティの値を oracle から System に変更します。
asadmin create-jdbc-connection-pool --user admin --password adminadmin --host sas.sun.com --port 8888 --instance server1 --restype javax.sql.XADataSource --datasourceclassname oracle.jdbc.xa.client.OracleXADataSource --description "Sample Jdbc Connection Pool" --property User="oracle":Password="oracle":URL="jdbc¥:oracle¥:thin¥:@oracleserver.sun.com¥:1521¥: ORA" SampleJdbcConnectionPool
- 次のコマンドを実行して、User プロパティを変更します。
asadmin set -u admin -w adminadmin -H sas.sun.com -p 8888 server1.jdbc-connection-pool.SampleJdbcConnectionPool.property.User="System"
ユーザーの名前が Oracle から System に変更されます。
- ユーザー名を変更したら、次のコマンドを実行して変更を適用します。
asadmin reconfig --user admin --password adminadmin --host sas.sun.com --port 8888 server1
SampleJdbcResource という JDBC リソースの作成: 次の方法で、JDBC リソースを作成できます。JDBC リソースを作成する構文は次のとおりです。
asadmin create-jdbc-resource --user admin_user [--password admin_password] [--host localhost] [--port 4848] [--secure | -s] [--instance instancename] --connectionpoolid id [--enabled=true] [--description text] [--property (name=value)[:name=value]*] jndiname
- 次のコマンドを実行して、SampleJdbcResource という JDBC リソースを作成します。
asadmin create-jdbc-resource --user admin --password adminadmin --host sas.sun.com --port 8888 --instance server1 --description "Sample Jdbc Resource" --connectionpoolid SampleJdbcConnectionPool jdbc/SampleJdbcResource
このコマンドを実行すると、JDBC リソースが作成され、次のメッセージが表示されます。
Created the external JDBC resource with jndiname = jdbc/SampleJdbcResource
- 次のコマンドを実行して、Sun ONE Application Server のインスタンスに変更を適用します。
asadmin reconfig --user admin --password adminadmin --host sas.sun.com --port 8888 server1
- 次のコマンドを実行して、server1 インスタンスのすべての JDBC リソースをリスト表示します。
asadmin list-jdbc-resources --user admin --password adminadmin --host sas.sun.com --port 8888 server1
接続プールについて
接続を取得するときに、アプリケーションはまず JNDI を使って DataSource をルックアップします。この場合のコード例は、次のようになります。
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/employee_ds");
DataSource を取得すると、アプリケーションコンポーネントは J2EE 配備記述子の <res-auth> 要素に設定されている値に応じて 2 つの方法で接続を取得できるようになります。この要素の値が Container であれば、アプリケーションは ds.getConnection() メソッドを使って接続を取得できます。この場合、サインオン情報は必要ありません。それ以外の値が設定されているときは、ds.getConnecion などのリソースマネージャから接続を取得するために、アプリケーションはサインオン情報 (userName, password) を指定する必要があります。
getConnection() へのすべての要求は、プールから供給されます。JDBC 接続プールは、server.xml に指定されているパラメータセットに基づいて作成されます。作成されたプールには、すぐに利用できる多数の接続が含まれます。このため、プールで現在利用できる接続によって ds.getConnection() 要求は満たされます。それ以前の接続がプールに返されなかった場合は、プールが空であるため、次の要求では増分の接続が作成されます。接続の作成は、プールに設定されている最大接続数によって制限されます。プールの実装は、作成された接続の数を追跡しています。getConnection() 要求に対して、プールが空であると見なされた場合、または作成した接続の数がプールの最大接続数と等しい場合は、その要求はブロックされます。これは、プールの共有が無効に設定されている場合にだけ生じる現象で、接続がプールに返されるまで継続します。
サーバーが稼働している限り、データベースがクラッシュしてから復旧した場合でも、接続プールは正常に機能し続けます。これは、「接続プールの設定」で説明した接続検証を有効にした場合にだけ利用できる機能です。
「検証方法」ドロップダウンリストで選択した値に応じて、プールの実装プログラムは次のパラメータを実行します。
- 接続検証タイプを auto-commit に設定した場合、システムは conn.getAutoCommit() メソッドを実行して接続が有効であるかどうかを確認する。メソッドが SQLException をスローしない場合は、接続は有効であると見なされる。auto-commit は、このパラメータのデフォルトオプションである
- 接続検証タイプを meta-data に設定した場合、接続のメタデータを調べるために conn.getMetaData() メソッドが実行される。SQLException がスローされない場合は、接続は有効であると見なされる
- 接続検証タイプを table に設定した場合、クエリ「Select * From <table-name>」が実行される。SQLException がスローされない場合は、接続は有効であると見なされる。
fail-all-connections (すべての接続を再確立) プロパティを有効にしたときは、プール内のいずれかの接続が無効な場合にすべての接続が閉じられ、再確立されます。それ以外の場合は、個々の接続の利用時に接続の中止と再確立が行われます。
プールの実装には、プールで利用できるすべての接続を再利用する機能もあります。指定したアイドル期間を過ぎると、アイドル状態の接続は閉じられ、プールのサイズは通常サイズに戻ります。プールのアイドル状態が長く続いた場合、プール内に通常数の利用可能な接続を維持するために、コンテナは古い接続を再確立する必要があります。プールの通常サイズと最大サイズを決定するときは、この点に注意する必要があります。
JDBC 接続プールの監視
プールサイズの設定が適切であるかを判断するには、プールの動作を定期的に監視します。次の表は、監視できる JDBC 接続プールパラメータの一覧です。
ただし、監視を有効にするメカニズムや監視可能な属性は、将来のリリースで向上する可能性があります。
   監視可能な JDBC 接続プールのパラメータ
属性名
データ型
説明
total-threads-waiting
整数
JDBC 接続を待機するスレッド総数
total-outbound-connections
整数
JDBC 接続検証の失敗総数
total-connections-timed-out
整数
タイムアウトになった接続要求の総数
接続の共有について
同じリソースマネージャを使う J2EE アプリケーションが複数の接続を必要とする場合、同じトランザクションの範囲内で接続を共有させることができます。トランザクションの範囲内という言葉の意味については、次の例を参考にしてください。
Bean_A がトランザクション (Tx1) を開始し、接続を取得します。次に、Bean_A は同じトランザクション (Tx1) で Bean_B 内のメソッドを呼び出します。Bean_B が同じ DataSource からの接続を必要とし、同じサインオン情報が必要となる場合は、同じ接続が共有され、Bean_A だけがトランザクションを完了することは明白です。また、接続の共有は、J2EE 配備記述子でリソースの共有が Shareable に設定されている場合にだけ行われます。接続の共有が適さない場合は、配備記述子でリソースの共有を Unshareable に設定します。Sun ONE Application Server では、パフォーマンス向上のために接続の共有をサポートしています。
JDBC トランザクションについて
トランザクションは、実行、完了され、さらにコミットまたはロールバックされた 1 つまたは複数のステートメントから構成されます。commit メソッドまたは rollback メソッドが呼び出されると、現在のトランザクションが終了され、新しいトランザクションが開始されます。
一般に、新しい接続オブジェクトはデフォルトでは auto-commit モードに設定されているため、ステートメントが完了すると、そのステートメントで commit メソッドが自動的に呼び出されます。この場合、各ステートメントは個別にコミットされるため、トランザクションは 1 つのステートメントだけから構成されます。auto-commit モードを無効にすると、commit メソッドまたは rollback メソッドが明示的に呼び出されるまでトランザクションは終了しません。このため、いずれかのメソッドを最後に呼び出してから実行されたすべてのステートメントがトランザクションに含まれます。この場合、トランザクションのすべてのステートメントはグループとしてコミットまたはロールバックされます。
commit メソッドは、SQL ステートメントがデータベースに加えたすべての変更を永続化し、そのトランザクションが保持するすべてのロックを解放します。rollback メソッドは、このような変更を破棄します。
1 つのトランザクションに 2 つのアップデートが含まれる場合、一方のアップデートが反映されなければ、もう一方のアップデートも反映させたくないことがあります。これは、auto-commit を無効にして、2 つのアップデートを 1 つのトランザクションにグループ化することで可能になります。両方のアップデートが成功した場合は、commit メソッドが呼び出され、両方のアップデートが永続化されます。一方または両方のアップデートが失敗した場合は、rollback メソッドが呼び出され、値はどちらのアップデートも実行される前の状態に戻されます。ほとんどの JDBC ドライバはトランザクションをサポートしています。
javax.sql パッケージに含まれるクラスとインタフェースは、接続オブジェクトを複数の DBMS サーバーに接続する分散トランザクションの一部として利用できます。分散トランザクションで接続オブジェクトを利用するには、中間層サーバーの分散トランザクションインフラストラクチャに対して働きかけるように実装された DataSource オブジェクトが接続オブジェクトを生成する必要があります。DriverManager によって生成される接続オブジェクトとは異なり、このような DataSource オブジェクトが生成する接続オブジェクトの auto-commit モードはデフォルトで無効に設定されます。一方、DataSource オブジェクトの標準的な実装は、DriverManager クラスによって生成される接続オブジェクトとまったく同じオブジェクトを生成します。
分散トランザクションの一部に接続オブジェクトが使われている場合、commit メソッドまたは rollback メソッドの実行タイミングはトランザクションマネージャによって決定されます。このため、接続オブジェクトが分散トランザクションに参加している場合は、Connection.commit メソッドや Connection.rollback メソッドの呼び出し、接続の auto-commit モードの有効化など、接続の開始と終了に影響する処理をアプリケーションは一切実行できません。このような処理は、トランザクションマネージャによる分散トランザクションの処理を妨害します。
JavaMail リソースについて
JavaMail API は、メッセージストアに格納されている電子メールメッセージにアクセスしたり、メッセージトランスポートを使って電子メールメッセージを作成および送信したりするための API です。インターネット標準 MIME メッセージに固有のサポートも含まれます。メッセージストアとトランスポートへのアクセスには、ストアとトランスポートに固有のプロトコルをサポートするプロトコルプロバイダを使って行われます。JavaMail API 仕様は特定のプロトコルプロバイダを必要としませんが、JavaMail には IMAP メッセージストアプロバイダと SMTP メッセージトランスポートプロバイダが含まれます。
JavaMail API は、メールシステムを構成するオブジェクトを定義する抽象クラスのセットを提供します。このAPI は、Message、Store、Transport などのクラスを定義します。API を拡張したり、サブクラスに分割することで、必要に応じて新しいプロトコルや機能を追加できます。さらに、この API は抽象クラスの具体的なサブクラスも提供します。これらのサブクラスには MimeMessage や MimeBodyPart が含まれ、一般に広く利用されているインターネットメールプロトコルを実装しています。
JavaMail API は、IMAP、MAPI、CMC、c-client、およびその他の電子メールメッセージングシステム API から多くを得ています。JavaMail API は、各種メッセージングストア、各種メッセージ形式、各種メッセージトランスポートなど、さまざまなメッセージングシステムの実装をサポートしています。JavaMail API は、クライアントアプリケーションの API を定義する基本的なクラスとインタフェースのセットを提供します。開発者は、JavaMail クラスをサブクラスに分割し、IMAP、POP3、SMTP など、特定のメッセージングシステムの実装を提供することができます。
この節では次の項目について説明します。
- JavaMail によるメッセージ処理のプロセスについて
- JavaMail のアーキテクチャコンポーネントについて
- JAF (JavaBeans Activation Framework) について
- JavaMail の設定パラメータについて
- JavaMail セッション参照の J2EE 配備記述子
- Sun ONE Application Server 配備記述子のエントリ
- JavaMail セッションの新規作成
- リソースの詳細プロパティの設定
JavaMail によるメッセージ処理のプロセスについて
JavaMail API は、一般的なクライアントアプリケーションの標準的なメール処理プロセスを構成する、次の機能を実行します。
- ヘッダー属性の集合、および Content-Type ヘッダーフィールドに指定されたデータタイプのデータブロックから構成されたメールメッセージを作成する。JavaMail は、Part インタフェースと Message クラスを使ってメールメッセージを定義する。メッセージにデータを含めるときは、JAF 定義による DataHandler オブジェクトを使用する
- ユーザーを認証し、メッセージストアとメッセージトランスポートへのアクセスを制御するセッションオブジェクトを作成する
- 受信者リスト宛てにメッセージを送信する
- メッセージストアからメッセージを取得する
- 取得したメッセージに対して高レベルのコマンドを実行する。表示や印刷などの高レベルコマンドは、JAF が認識する JavaBeans による実装を前提とする
注 現時点では、JavaMail のフレームワークは、メッセージ配信、セキュリティ、接続解除状態での処理、ディレクトリサービス、フィルタ機能をサポートするメカニズムを定義していません。
次の図は、JavaMail API によるメッセージ処理プロセスを示しています。
   この図は、JavaMail API のメッセージ処理プロセスを示しています。
JavaMail API の設定は、静的なファクトリメソッドを使って javax.mail.Session を作成することで行われます。Sun ONE Application Server は JNDI を使ってセッションオブジェクトを要求し、セッションオブジェクトが必要であることを配備記述子の resource-ref 要素に記録します。JavaMail API セッションオブジェクトは、リソースファクトリと見なされます。
javax.mail.internet.InternetAddress タイプのアドレスと、javax.mail.internet.MimeMessage タイプのメッセージを処理できるメッセージトランスポートが提供されます。デフォルトのメッセージトランスポートは、javax.mail.Transport クラスの送信メソッドを使ってこのようなメッセージを送信できるように適切に設定する必要があります。
JavaMail API の抽象層は、すべてのメールシステムがサポートするメール処理に対応したクラス、インタフェース、および抽象メソッドを宣言します。抽象層を構成する API 要素は、標準のデータタイプをサポートするために、必要に応じてサブクラスに分割および拡張されます。また、必要に応じて、メッセージアクセスプロトコルとメッセージトランスポートプロトコルのインタフェースとして機能します。
インターネット実装層は、インターネット標準の RFC822 と MIME を使って抽象層の一部を実装します。
JavaMail のアーキテクチャコンポーネントについて
ここでは、JavaMail のアーキテクチャを構成する次の主要コンポーネントについて説明します。
Message クラス
Message クラスは、メールメッセージの属性セットとコンテンツを定義する抽象クラスです。Message クラスの属性は、アドレス情報を指定し、コンテンツの構造を定義します (コンテンツタイプを含む)。コンテンツは、実際のデータを内包した DataHandler オブジェクトとして表されます。
Message クラスは Part インタフェースを実装します。Part インタフェースは、Message オブジェクトによって運ばれるデータコンテンツの定義と書式設定に必要な属性、およびメールシステムとのインタフェースの成功に必要な属性を定義します。Message クラスは、メッセージトランスポートシステムを経由したメッセージのルーティングに必要な From、To、Subject、Reply-To などの属性を追加します。フォルダに含まれる Message オブジェクトには、関連するフラグのセットがあります。JavaMail は、特定のメッセージング実装をサポートする Message サブクラスを提供します。
メッセージのコンテンツはバイトの集合、またはバイトの集合に対する参照で、Message オブジェクト内にカプセル化されます。JavaMail は、メッセージコンテンツのデータタイプや形式を認識できません。Message オブジェクトは、JAF (JavaBeans Activation Framework) という中間層を通じてコンテンツと対話します。この分離によって、Message オブジェクトはあらゆる種類のコンテンツを処理できます。また、同じ API メソッドを呼び出すことで任意の適切な転送プロトコルを使ってコンテンツを転送できます。メッセージの受信側は、通常はコンテンツのデータタイプと形式を認識し、コンテンツの処理方法を理解できます。
JavaMail API は、各 Bodypart がそれぞれの属性とコンテンツを定義する複数パートの Message オブジェクトもサポートしています。
メッセージの格納と取得
メッセージは Folder オブジェクトに格納されます。Folder オブジェクトにはサブフォルダだけでなくメッセージも格納できるので、フォルダ階層のようなツリー構造になります。Folder クラスは、メッセージをフェッチ、修正、コピー、および削除するメソッドを宣言します。Folder オブジェクトは、イベントリスナーとして登録されているコンポーネントにイベントを送信することもできます。
Store クラス
Store クラスは、フォルダ階層とメッセージを格納するデータベースを定義します。また、Store クラスは、フォルダにアクセスして格納されているメッセージを取得するためのアクセスプロトコルも指定します。Store クラスは、データベースへの接続の確立、フォルダのフェッチ、および接続を閉じるために適用されるメソッドも提供します。メッセージアクセスプロトコル (IMAP、POP3 など) を実装するサービスプロバイダは、Store クラスをサブクラスに分割するところから処理を開始します。通常、ユーザーは特定の Store 実装に接続することでメールシステムとのセッションを開始します。
メッセージの構成とトランスポート
クライアントは、適切な Message サブクラスをインスタンス化して新しいメッセージを作成します。これにより、受信側のアドレスや件名などの属性が設定され、Message オブジェクトにコンテンツが挿入されます。最後に、Transport 送信メソッドが呼び出され、メッセージが送信されます。Transport クラスは、メッセージを送信先アドレスにルーティングするトランスポートエージェントを作成します。このクラスは、受信者リストにメッセージを送信するメソッドを提供します。Message オブジェクトを指定して Transport 送信メソッドを呼び出すと、送信先アドレスに基づいて適切なトランスポートが識別されます。
Session クラス
Session クラスは、メールを利用できるクライアントとネットワークの間のインタフェースを定義する、グローバルおよびユーザー単位のメール関連プロパティを定義します。
JavaMail システムコンポーネントは、セッションオブジェクトを使って特定のプロパティを設定、取得します。また、Session クラスは、デスクトップアプリケーションによる共有が可能で、デフォルトで認証されるセッションオブジェクトを提供します。Session クラスは、最終の具体的なクラスです。これをサブクラスに分割することはできません。また、Session クラスは、特定のアクセスプロトコルとトランスポートプロトコルを実装する Store オブジェクトと Transport オブジェクトのファクトリとしても機能します。セッションオブジェクトで、適切なファクトリメソッドを呼び出すことで、クライアントは特定のプロトコルをサポートする Store オブジェクトと Transport オブジェクトを取得できます。
JAF (JavaBeans Activation Framework) について
JavaMail は、メッセージデータのカプセル化、およびデータと対話するコマンドの処理に JAF (JavaBeans Activation Framework) を使います。メッセージデータとの対話は JAF が認識する JavaBeans を介して行う必要があり、これは JavaMail API によって提供されません。
JAF の標準拡張を利用することで Java テクノロジを使う開発者は、データの任意の部分のタイプの特定、そのデータへのアクセスのカプセル化、そのデータで利用できる機能の確認、指定処理を実行する適切な Bean のインスタンス化といった標準サービスの利点を活用することができます。たとえば、ブラウザが JPEG 画像にアクセスした場合、このフレームワークによって、ブラウザはデータのストリームを JPEG 画像として認識できます。さらに、特定したタイプに基づいて、その画像を操作または表示できるオブジェクトを探し、インスタンス化することができます。
JAF API は、さまざまな MIME データタイプをサポートしています。Java Mail API には、次の表に示す Java プログラミング言語のタイプに対応する MIME データタイプをサポートするために、javax.activation.DataContentHandlers を含める必要があります。
   JavaMail API の MIME データタイプと Java のタイプのマッピング
MIME タイプ
Java のタイプ
Text/Plain
java.lang.String
Multipart/
javax.mail.internet.MIME.Multipart
Message/rfc822
javax.mail.internet.MIME.Message
JAF は、MIME データタイプのサポートを Java プラットフォームに統合します。MIME バイトストリームと Java プログラミング言語オブジェクトは、avax.activation.DataContentHandlerobjects を使って相互に変換できます。データの表示や編集など、MIME データを処理する JavaBeans コンポーネントを指定できます。また、JAF にはファイル名の拡張子を MIME タイプにマップするメカニズムも用意されています。JavaMail API は、メッセージに含まれるデータの処理に JAF を使用します。通常の J2EE アプリケーションは JAF を直接使う必要はありませんが、電子メールを利用するアプリケーションを洗練させる場合には必要になることがあります。
JavaMail の設定パラメータについて
Sun ONE Application Server の JavaMail リソースは、次の設定パラメータを使用します。これらの設定パラメータは、server.xml ファイルの mail-resource 要素から読み込まれる名前と値のペアです。
- JNDI Name
JNDI 名は、J2EE アプリケーションが参照するこのメールリソースの名前
- Enabled
enabled 設定パラメータは、このメールリソースを JNDI ツリーにパブリッシュし、参照可能にするかどうかを指定する。無効なリソースを参照した J2EE アプリケーションは NameNotFoundException 例外を受け取る
- store-protocol
デフォルトのメッセージアクセスプロトコルを指定する。Session.getStore() メソッドは、このプロトコルを実装する Store オブジェクトを返す。クライアントは、Session.getStore(String protocol) メソッドを使ってこのプロパティをオーバーライドし、別のプロトコルを明示的に指定できる
- store-protocol class
上で指定したストアプロトコルを実装するクラスの名前を指定する。このクラスのデフォルト名は com.sun.mail.imap.IMAPStore
- transport-protocol
デフォルトのトランスポートプロトコルを指定する。Session.getTransport() メソッドは、このプロトコルを実装する Transport オブジェクトを返す。クライアントは、Session.getTransport(String protocol) メソッドを使ってこのプロパティをオーバーライドし、別のプロトコルを明示的に指定できる
- transport-protocol class
上で指定したトランスポートプロトコルを実装するクラスの名前を指定する。このクラスのデフォルト名は com.sun.mail.smtp.SMTPTransport
- host
デフォルトのメールサーバーを指定する。Store オブジェクトと Transport オブジェクトの接続メソッドは、プロトコル固有の host プロパティが見つからない場合にこのプロパティを使ってターゲットホストを特定する
- user
メールサーバーへの接続時に渡すユーザー名を指定する。Store オブジェクトと Transport オブジェクトの接続メソッドは、プロトコル固有の username プロパティが見つからない場合にこのプロパティを使ってユーザー名を取得する
- from
現在のユーザーの返信先アドレスを指定する。InternetAddress.getLocalAddress メソッドが現在のユーザーの電子メールアドレスを指定するときに使われる
- debug
初期デバッグモードを指定する。このプロパティを true に設定すると、デバッグモードがオンになり、false に設定するとオフになる
- mail-<protocol>-host
プロトコル固有のデフォルトメールサーバーを指定する。これは、mail.host プロパティに優先して適用される。このプロパティは、store-protocol 属性の値に応じて設定できる。store-protocol の値が IMAP または POP の場合、プロパティにそれぞれ mail.imap.host または mail.pop3.host という名前を追加する必要がある。特定のプロパティの値は、メールシステムの設定に合わせて設定する必要がある。たとえば、store-protocol を IMAP に設定した場合、mail-imap-host というプロパティ名には spaceduck.acme.com という値が追加される
- mail-<protocol>-user
メールサーバーへの接続に適用される、プロトコル固有のデフォルトユーザー名を指定する。これは、mail.user プロパティに優先して適用される。store-protocol 属性の設定に応じて、このプロパティの値は mail.imap.user または mail.pop3.user となる。たとえば、store-protocol を IMAP に設定した場合、mail-imap-user というプロパティ名には fredbloggs という値が追加される
JavaMail セッション参照の J2EE 配備記述子
JavaMail リソースをサーバーに登録すると、JNDI ルックアップを使って J2EE アプリケーションコンポーネントがこれを参照できるようになります。リソースマネージャ接続ファクトリを参照するアプリケーションを配備するには、コンポーネントプロバイダは、標準の J2EE 1.3 配備記述子にすべてのリソースマネージャ接続ファクトリ参照を宣言する必要があります。
J2EE 1.3 記述子の JavaMail 参照の要素は次のとおりです。
<resource-ref>
<description>
メールの送信に利用される JavaMail リソース
</description>
<res-ref-name>mail/MyMailSession</res-ref-name>
<res-type>javax.mail.Session</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Sun ONE Application Server 配備記述子のエントリ
配備担当者は、メールリソースを参照する配備コンポーネントごとに、コンポーネントで使われるリソースの名前と、ネーミングサービスに DataSource が登録されている実際の JNDI 名をマップする必要があります。配備ツールを使えば、このマッピングは簡単に行えます。このマッピングは、Sun ONE Application Server 固有の xml ファイルに登録されます。次に、このマッピングを含む Sun ONE Application Server 固有の XML の一部を示します。
<resource-ref>
<res-ref-name>mail/MyMailSession</res-ref-name>
<jndi-name>mail/Session</jndi-name>
</resource-ref>
JavaMail セッションの新規作成
管理インタフェースを使って JavaMail セッションを設定できます。新しい JavaMail セッションを作成、設定するには、次の手順を実行します。
- 管理インタフェースの左側のペインで、新たに JavaMail セッションを作成するSun ONE Application Serverインスタンスを展開します。
- 「Java メールセッション」をクリックします。管理インタフェースの右側のペインに次のような「JavaMail セッションの設定」のウィンドウが表示されます。
   JavaMail セッションの設定
- 作成している JavaMail セッションの名前を「JNDI 名」テキストフィールドに入力します。JavaMail リソースをサーバーに登録すると、JNDI ルックアップを使って J2EE アプリケーションコンポーネントがこれを参照できるようになります。
- デフォルトメールサーバーの DNS 名を「メールホスト」テキストフィールドに入力します。Store オブジェクトと Transport オブジェクトの接続メソッドは、プロトコル固有の host プロパティが見つからない場合にこのプロパティを使ってターゲットホストを特定します。
- メールサーバーへの接続時に渡すユーザー名を「デフォルトユーザー」テキストフィールドに入力します。Store オブジェクトと Transport オブジェクトの接続メソッドは、プロトコル固有の username プロパティが見つからない場合にこのプロパティを使ってユーザー名を取得します。
- 現在のユーザーのデフォルトの返信先アドレスを「デフォルトの返信用アドレス」フィールドに入力します。デフォルトのアドレスは、「username@host」の形式で指定する必要があります。
- この JavaMail セッションの説明を「説明」フィールドに入力します。
- 「Java メールセッションを有効」ボックスにチェックマークをつけて、作成した JavaMail セッションを有効にします。
- 「了解」をクリックして、新たに設定した JavaMail セッションを保存します。
リソースの詳細プロパティの設定
管理インタフェースを使って、新しい JavaMail セッションにいくつかの追加プロパティを設定できます。プロパティの名前と値のペアは、使用するメイルプロトコルによって異なります。また、これらのプロパティを server.xml ファイルに直接設定することもできます。
追加プロパティを設定するには、次の手順を実行します。
- 管理インタフェースの左側のペインで、設定を変更する JavaMail セッションを含むSun ONE Application Serverインスタンスを展開します。
- 「Java メールセッション」をクリックします。管理インタフェースの右側のペインの「JavaMail セッションの新規作成」で説明したメイン設定セクションの下に、次のような「JavaMail セッションリソースの追加設定」のウィンドウが表示されます。
   JavaMail セッションリソースの追加設定
- POP3 や IMAP など、この JavaMail セッションに適用するストアプロトコルを「ストアプロトコル」テキストフィールドに入力します。
- 例に示されるように、指定したストアプロトコルのクラス名を「ストアプロトコルクラス」テキストフィールドに入力します。
- たとえば SMTP など、JavaMail セッションに適用するトランスポートプロトコルを「トランスポートプロトコル」テキストフィールドに入力します。
- 例に示されるように、このセッションに指定したトランスポートプロトコルのクラス名を「トランスポートプロトコルクラス」テキストフィールドに入力します。
- この JavaMail セッションのデバッグを有効にするときは、「デバッグを有効」ボックスにチェックマークをつけます。このボックスにチェックマークをつけると、デバッグモードが有効になります。
- 「了解」をクリックして、追加プロパティの設定を保存します。
次に、メールリソースのすべての設定の例を示します。
<mail-resource
jndi-name = "mail/Session"
enabled = "true"
store-protocol = "imap"
store-protocol-class = "com.sun.mail.imap.IMAPStore"
transport-protocol = "smtp"
transport-protocol-class = "com.sun.mail.smtp.SMTPTransport"
host = "gopostal.acme.com"
user = "kingkong"
from = "kingkong@acme.com"
debug = "false">
<property name = "mail-imap-host" value = "spaceduck.acme.com"/>
<property name = "mail-imap-user" value = "fredbloggs"/>
</mail-resource>