SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Jakarta Commonsを使ってJDKクラスを拡張する:パート3

Commons CLI/VFS/Configuration/Poolの利用

Pool

 Commons Poolは、どんなオブジェクトでもプールできるすばらしいフレームワークです。JDBC接続、スレッド、業務用オブジェクト、JNDI接続のプールにも十分に役立つはずです。

 サンプルアプリケーションではJNDI接続プールを利用します。このサンプルの実行にはJNDI互換のディレクトリサーバーが必要になります。また、このサンプルではActive Directory Application Mode(ADAM)を使用しますが、ADAMはこちらからダウンロードできます。それでは、このサンプルがCommons Poolを使ってどのようにJNDI接続をプールするのかを見ていきましょう。

 リスト16は、JNDIの操作を行うメソッドを公開するインターフェイスです。

リスト16 JNDI操作用メソッドを公開するインターフェイス
public interface IJNDIConnection {

    /**
     * Execute the given query against the directory server.
     *
     * @param query JNDI query of the form ((objectclass=user)(cn=john))
     * @return Search result
     * @throws NamingException Directory server error
     */
    NamingEnumeration executeQuery(String query)
        throws NamingException;

    /**
     * Fetch the attributed of a given DN of an object.
     *
     * @param dn Distinguished name of the object
     * @return Attributes of an object
     * @throws NamingException Directory server error
     */
    Attributes getAttributes(String dn) throws NamingException;
}

 このin.co.narayanan.commons.pool.JNDIConnectionクラスは、さきほどのインターフェイスを実装しており、javax.naming.directory.DirContextクラスを使って、要求されるJNDI操作を実行します。リスト17のコードは、プールされた接続をどのように取得して利用するかを示すテストケースクラスTestPoolの一部です。

リスト17 接続プールの使用方法
String host = "localhost";
String port = "389";
String binDN = "CN=guest,CN=Users,DC=narayanan,DC=co,DC=in";
String password = "guest";
String baseDN = "DC=narayanan,DC=co,DC=in";

JNDIConnectionManager manager =
    JNDIConnectionManager.getJNDIConnectionManager(
        host,
        port,
        binDN,
        password,
        baseDN);
IJNDIConnection connection = manager.getConnection();

String query = "(objectclass=container)";
NamingEnumeration users = connection.executeQuery(query);
while (users.hasMoreElements()) {
    System.out.println(users.next());
}

 このコードは、JNDIConnectionManagerを使って接続プールからIJNDIConnectionへの参照を取得したうえで、簡単な検索クエリを実行します。Commons Poolの利用では、org.apache.commons.pool.PoolableObjectFactoryインターフェイスの各メソッドを実装して、その参照をorg.apache.commons.pool.impl.GenericObjectPoolインターフェイスの実装に渡す、というのが基本的な手順です。ほとんどの場合は、org.apache.commons.pool.impl.GenericObjectPoolクラス ― ObjectPoolのデフォルト実装 ― で十分に間に合います。リスト18のコードは、Commons Poolによる新たなオブジェクトの要求時にJNDI接続を作成するJNDIConnectionFactoryの一部です。

リスト18 JNDIConnectionFactoryの実装
public class JNDIConnectionFactory implements PoolableObjectFactory {
    private JNDIConnectionInfo connInfo;
    public JNDIConnectionFactory(String host,
            String port,
            String bindDN, 
            String password,
            String baseDN) {
        connInfo = new JNDIConnectionInfo(
            host, port, bindDN, password, baseDN);
    }
 
    public Object makeObject() throws Exception {
        Hashtable dirProps = connInfo.getJNDIConnectionProps();
        DirContext dirContext = new InitialDirContext(dirProps);
        return dirContext;
    }
 
    public void destroyObject(Object context) throws Exception {
        DirContext dirContext = (DirContext)context;
        dirContext.close();
    }
    // remaining methods
    // inner class JNDIConnectionInfo
}

 太字の行は、Commons Poolからの要求に応じてDirContextの生成と破棄をどのように行うかを示しています。このObjectPoolを実装したクラスはmakeObjectメソッドとdestroyObjectメソッドを適切に呼び出します。リスト19は、JNDIConnectionManagerクラスの一部です。

リスト19 プールから接続を取得するマネージャクラス
public class JNDIConnectionManager {
    // remaining declarations
    private GenericObjectPool pool;
    private PoolableObjectFactory factory;

    private JNDIConnectionManager(
        String host,
        String port,
        String bindDN,
        String password,
        String baseDN) {
        factory = new JNDIConnectionFactory(
            host, port, bindDN, password, baseDN);
        pool = new GenericObjectPool(factory);
    }

    // remaining code

    public IJNDIConnection getConnection() {
        try {
            return new JNDIConnection((DirContext)pool.borrowObject());
        } catch (Exception e) {
            return null;
        }
    }

    public void returnConnection(IJNDIConnection connection) {
        try {
            pool.returnObject(
                ((JNDIConnection)connection).getContext());
        } catch (Exception e) {
            System.out.println("Unable return the object back to pool");
        }
    }
}

 このコードでは、JNDIConnectionFactoryの参照をGenericObjectPoolに渡すことでJNDI接続を作成しています。強調表示された行は、プールとの間でこの接続の取得と返却をどのように行うかを示しています。

 Commons PoolはすべてのJavaアプリケーションで間違いなく役に立ちます。Javaアプリケーションではリソースのプールが共通の要件になっているためです。また、ニーズに合わせてGenericObjectPoolクラスをカスタマイズすることも可能です(詳細については、このクラスのjavadocを参照)。

まとめ

 Jakarta Commonsを紹介するシリーズの最終回では、次の内容を取り上げました。

  • Commonsのさまざまなコンポーネントが提供する豊富な機能
  • ユーティリティクラスの特定のコンポーネントやメソッドの具体的な用途
  • さまざまなAPIのパッケージとクラスの概要

 これからJavaアプリケーションをデザインしたり開発したりするときには、有用なクラスを選んで適切に使用できることでしょう。

本シリーズの以前の記事

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Narayanan A.R.(Narayanan A.R.)

テスト駆動開発、アジャイル方法論、Javaテクノロジ、およびデザインパターンの熱烈な擁護者。Javaテクノロジを使ったソフトウェアのデザインおよび開発に携わって数年になる。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/313 2006/04/11 19:10

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー