JNDIは、ネームサービスやディレクトリーサービスにアクセスする方法を提供している。J2EEの仕様のひとつ。
いきなりネーミングサービスやらディレクトリーサービスと言われても「何の事やら?」だが。
乱暴な言い方をすれば、JNDIはプロパティーの取得と同じ。
プロパティーでは、ローカルに置いたプロパティーファイルに「キー = 値」という行を複数書いておき、実行時にキーを指定することによって値(文字列)を取得する。
JNDIでも、キーを指定して値を取得する。
JNDIとプロパティーの違い | 例 |
---|---|
JNDIでは値は文字列だけでなくJavaのオブジェクトも返せる。 | DBのデータソースの取得などによく使われる。 |
リモートのサーバーが持っている情報でもネットワーク経由で取得できる。 | DNS(ドメイン・ネーム・システム:インターネットでよく使われる、Javaに限らない機能)等の呼び出しが出来るらしい。 |
ネットでJNDIを検索してみると、前者と後者のどちらかに主眼を置いて解説されていることが多い。
なので、この2パターンが存在することは知っておかないと、混乱することになる。
名前から情報を取ってくるのでプロパティーファイルから情報を持ってくるのと同じような感じだが、オブジェクトを返すこともできるので、より高機能と言えそう。
また、サーバーなので、ネットワーク越しにデータを持ってくることもできる。だからサービスと呼ぶんだろう。
JNDIは、「問合せ(名前)に対する答え(オブジェクトや属性)を返すサービス」を提供するための仕様。
そのサービスがネームサービスやディレクトリーサービスと呼ばれるもの。
JNDIでは、「キーと値を保持しているサーバーに
、キーを指定して問い合わせる
(値を返してもらう)」という形をとる。
なので、その“答えを返すサーバー”(サービスプロバイダー(SP:サービスの提供者))が必要となる。
DNSの場合は まさにDNSサーバーへ問い合わせている。
DBのデータソースの取得でも、データソースを保持しているサーバーに問い合わせている。「そんなサーバー有るか?」と思うが、実はAPサーバーがJNDIのサービスを提供している(APサーバーがJNDIのサービスも機能に含んでいる ということ)。
つまり「TomcatやJBossの設定ファイルに書いた情報」や「WebLogicの管理画面から入力した情報」が、JNDIのサービスとして実行時に返されている
。
JNDIを使って値を取得するには、コンテキストと呼ばれるオブジェクト(これがサービスプロバイダーを意味する)を生成し、それに対して問い合わせる(lookupメソッドを呼ぶ)。
import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException;
Context ctx = new InitialContext(); //サーブレット(APサーバー管理下のアプリ)からは、これで取得できる String val; try { val = (String) ctx.lookup("キー"); } finally { ctx.close(); }
Hashtable env = new Hashtable(); env.put(〜); //サービスプロバイダーを指定する情報をセット Context ctx = new InitialContext(env); //バッチ(APサーバーの管理外のアプリ)からは、環境情報を指定して取得する String val; try { val = (String) ctx.lookup("キー"); } finally { ctx.close(); }
サービスプロバイダーを指定する具体的な値や問い合わせるキーの具体的な値は、サービスプロバイダーによって異なる。
探したいキー(JNDI名)が見つからないと、lookup()においてjavax.naming.NamingExceptionが発生する。[2008-08-03]
JNDIを試そうとすると、絶対に(?!)NamingExceptionに悩まされることになると思う(苦笑)
こういう時は まず、思っているJNDI名が登録されているかどうか、プロバイダー(APサーバー)上で確認してみるのがよい。
→WebLogic10のJNDIツリー [2008-08-03]
→JBossのJNDIView [2008-08-15]