よくある質問とその答え
JNDIとは何ですか?
技術評論社発行「BEA WebLogic Server 8.1J EJB 2.0徹底攻略」Appendix Bより抜粋
JNDI(Java Naming and Directory Interface)とはその名のとおり、名前およびディレクトリサービスのためのインタフェース仕様のことで、J2SEにてAPIが定められている(J2SE1.3以降)。名前サービスとは、オブジェクトに名前を関連付けて保管し(バインド)、あとからその名前でオブジェクトを検索(ルックアップ)できるようなサービスを提供するものを指す。ディレクトリサービスとは、ディレクトリオブジェクトを扱えるように名前サービスの拡張を行っている名前サービスの一種である。ディレクトリオブジェクトとは、オブジェクトの特殊な形態であり、属性を関連付けられるようになっているものだ。JNDIのクライアントAPIでは、名前サービスはjavax.namingパッケージ、ディレクトリサービスはjavax.naming.directoryパッケージにてまとめられ、提供されている。名前サービスでは、コンテキスト内でユニークな名前をつけて保存したオブジェクトを名前で検索できるが、ディレクトリサービスではさらに、名前と属性から複数のオブジェクトを検索できる。EJBをはじめとするJ2EEサービスは、いろいろな場所でJNDIをオブジェクト検索のために使用しているが、特定のオブジェクトを特定の名前で検索できれば十分なので、名前サービスのみを使用している。通常のJ2EEアプリケーションがjavax.naming.*をインポートすれば十分なのはそのためである。
コンテキスト(Context)とイニシャルコンテキスト(InitialContext)
コンテキストとは、バインディングオブジェクト(名前とオブジェクトのペア)の集合に対し、基本的なアクセス・インタフェースを提供するものであり、javax.naming.Contextであらわされる。イニシャルコンテキストは、コンテキストの具象クラスであり、JNDIサービス実装にアプリケーションがアクセスするための入り口となるコンテキストであり、javax.naming.InitialContextであらわされる。アプリケーションがJNDIサービスを使用してオブジェクトを登録したり検索したりするには、なによりもまず、このイニシャルコンテキストを取得することから始まる。例えば、WLS上のアプリケーションがそのWLSが提供するJNDIサービスからオブジェクトを検索する方法(図A)は、次のようにコーディングできる。
Context ctx = new InitialContext(); Object obj = ctx.lookup( "オブジェクトにつけた名前" );

引数なしでInitialContextオブジェクトを作ろうとすると、WLSはファクトリweblogic.jndi.WLInitialContextFactoryを使用してコンテキストを生成し、返す。図Bのように、Javaクライアントアプリケーション、もしくはサーブレットやEJBが他のWLSインスタンスのJNDIサービスを利用する場合、InitialContextオブジェクトの生成時に接続するWLSへのURLをハッシュテーブルで指定すればよい。その際、WLSではファクトリの指定が必要となるため、実際には次のようなプログラムとなる。
Hashtable env = new Hashtable(); env.put( Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory" ); env.put( Context.PROVIDER_URL, "t3://WLSホスト名:ポート番号" ); Context ctx = new InitialContext( env ); Object obj = ctx.lookup( "オブジェクトにつけた名前" );

文字列定数Context.INITIAL_CONTEXT_FACTORYは"java.naming.factory.initial"を、Context.PROVIDER_URLは"java.naming.provider.url"とそれぞれ定義されている。 4章で紹介しているアプリケーションでは、図BのようにEJB層とWeb層が分かれてデプロイされる環境でも動作するよう考慮したコーディングがなされている。具体的には、システムプロパティejbmarket.jndi.propertiesが設定されているかどうかを調べ、設定されている場合はそのファイルをJNDIのプロパティ設定とみなし、JNDIのイニシャルコンテキスト生成時に使用する。例えば、myjndi.propertiesというファイルの内容を次のようにしておき、
java.naming.factory.initial = weblogic.jndi.WLInitialContextFactory java.naming.provider.url = t3://ejb-wls-hostname:port-number
Web層のWLSサーバ起動時に、次のようにオプションを指定する。
> java -Dejbmarket.jndi.properties=myjndi.properties … weblogic.Server
このような面倒な実装方法を取らずに、次のように単にWeb層のWLS起動時にJNDIのプロパティを直接指定すればよいのではないか、と疑問に思う読者もいるかもしれない。
> java -Djava.naming.factory.initial= weblogic.jndi.WLInitialContextFactory -Djava.naming.provider.url= t3://ejb-wls-hostname:port-number … weblogic.Server
しかーし、これではうまくいかないのだ!なぜならWLSは自分自身でもJNDIサービスを使用しており、このようにWLSを起動してしまうと、自分のさまざまなサービスのためでも指定されたURLのJNDIサービスに接続しようとしてしまい、予期せぬ動作を引き起こしてしまう。