ポータブル・オブジェクト・アダプタ(POA)

ポータブル・オブジェクト・アダプタ(POA)とは

オブジェクト・アダプタは、オブジェクト参照を使用する要求と適切なコードを接続して、その要求にサービスを提供するメカニズムです。ポータブル・オブジェクト・アダプタ(POA)は、CORBA仕様によって定義された特別な種類のオブジェクト・アダプタです。POAは次の目標を満たすように設計されています。

このドキュメントでは、Java SEでのPOAの使用法の概要について説明します。POAの詳細については、CORBA 2.3.1仕様の第11章を参照してください。

POAの作成と使用

POAを作成して使用するための手順は、開発する特定のアプリケーションによって異なります。POAのライフ・サイクルでは、通常、次の手順を実行します。

  1. ルートPOAの取得
  2. POAのポリシーの定義
  3. POAの作成
  4. POAManagerの起動
  5. サーバントの起動 (Tieの起動を含む場合がある)
  6. POAからのオブジェクト参照の作成

次にこれらの各手順について詳しく説明します。

ステップ1: ルートPOAの取得

最初の手順は、1番目のPOAの取得です。このPOAは「ルートPOA」と呼ばれます。ルートPOAは、ORBによって管理され、ORB初期化インタフェースを使用するアプリケーションに「RootPOA」という初期オブジェクト名で提供されます。

ルートPOAオブジェクトを取得し、それをPOAにキャストするコードの例を次に示します。

      ORB orb = ORB.init( args, null );
      POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
ステップ2: POAのポリシーの定義

ポータブル・オブジェクト・アダプタ(POA)は、複数のORB実装で使用できるオブジェクト・アダプタを提供するために設計されており、異なるベンダーの実装を扱う場合も書き直す必要がないようになっています。

POAは、少なくともクライアントの立場からは持続オブジェクトが可能になるようにしています。つまり、サーバーが物理的に何度再起動されても、そのクライアントが関係する範囲では、これらのオブジェクトは常に稼働しており、オブジェクトに格納されたデータ値が維持されています。

POAを使用すると、オブジェクトの実装者は、オブジェクトの識別、状態、記憶領域、およびライフ・サイクルに関してより多くの制御を行うことができます。POAは、使用されるポリシーやデフォルト値を定義しないで作成できます。ルートPOAにはデフォルトで次のポリシーが定義されています。

次のコードは、RMI-IIOPを使ったPOAの例でのポリシーの設定方法を示しています。

      Policy[] tpolicy = new Policy[3];
      tpolicy[0] = rootPOA.create_lifespan_policy(
        LifespanPolicyValue.TRANSIENT );
      tpolicy[1] = rootPOA.create_request_processing_policy(
        RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY );
      tpolicy[2] = rootPOA.create_servant_retention_policy(
        ServantRetentionPolicyValue.RETAIN);

次に各ポリシーについて簡単に説明します。POAポリシーの詳細は、CORBA/IIOP 2.3.1仕様の第11章「Portable Object Adapter」を参照してください。

スレッド・ポリシー

このポリシーは、作成済みのPOAとともに使用されるスレッド・モデルを指定します。デフォルトはORB_CTRL_MODELです。

ThreadPolicyValueには、次の値を指定できます。

ライフタイム・ポリシー

このポリシーは、作成済みのPOA内で実装されるオブジェクトのライフ・タイムを指定します。デフォルトはTRANSIENTです。

LifespanPolicyValueには、次の値を指定できます。

オブジェクトID一意性ポリシー

このポリシーは、作成済みのPOA内で起動されるサーバントが一意のオブジェクトIDを持つ必要があるかどうかを指定します。デフォルトはUNIQUE_IDです。

IdUniquenessPolicyValueには、次の値を指定できます。

ID割当てポリシー

このポリシーは、作成済みのPOA内のオブジェクトIDがアプリケーションまたはORBのどちらによって生成されるかを指定します。デフォルトはSYSTEM_IDです。

IdAssignmentPolicyValueには、次の値を指定できます。

サーバント保持ポリシー

このポリシーは、作成されたPOAがアクティブなサーバントをActive Object Mapに保存するかどうかを示します。デフォルトはRETAINです。

ServantRetentionPolicyValueには、次の値を指定できます。

要求処理ポリシー

このポリシーは、作成されたPOAがどのように要求を処理するかを示します。デフォルトはUSE_ACTIVE_OBJECT_MAP_ONLYです。

RequestProcessingPolicyValueには、次の値を指定できます。

暗黙的起動ポリシー

このポリシーは、作成済みのPOAでサーバントの暗黙的な起動がサポートされるかどうかを指定します。デフォルト値はIMPLICIT_ACTIVATIONです。

ImplicitActivationPolicyValueには、次の値を指定できます。

ステップ3: POAの作成

アプリケーション開発者は、新しいPOAを作成することによって、新しいPOA用に選択した特定のポリシーを宣言し、異なるアダプタ・アクティベータおよびサーバント・マネージャ (これらは、必要時のPOAの起動とサーバントの起動を行うためにPOAが使用するコールバック・オブジェクト)を提供できます。オブジェクトIDはPOAに対して相対的に解釈されるため、アプリケーション開発者は、新しいPOAを作成することによってさらにオブジェクトの名前空間の区分けも行うことができます。また、新しいPOAを作成すると、開発者は、複数のオブジェクトのセットに対する要求の処理を個別に制御できます。

POAは、親のPOAに対するcreate_POAオペレーションを使用して、既存のPOAの子として作成されます。新しいPOAを作成するには、次の情報を渡します。

次のコードは、持続サーバーを使ったHello Worldの例でのPOAの作成方法を示します。

// Create a POA by passing the Persistent Policy
POA persistentPOA = rootPOA.create_POA("childPOA", null, 
   persistentPolicy ); 
ステップ4: POAManagerの起動

各POAオブジェクトにはPOAManagerオブジェクトが関連付けられます。POAManagerオブジェクトは、POAに対する要求をキューに入れるか破棄するかといった、関連POAの処理状態を制御します。POAManagerは、POAを停止することもできます。POAマネージャには、1つまたは複数のPOAオブジェクトを関連付けることができます。

POAManagerには、次の状態を指定できます。

これらの状態の詳細については、 POAManagerOperationsのjavadocを参照してください。

POAマネージャは、作成時に自動的に起動されません。次のコードは、持続サーバーを使ったHello Worldの例でのPOAManagerの起動方法を示します。この方法でPOAマネージャを起動しないと、POAマネージャはデフォルトではHOLD状態になっているため、Servantに対するすべての呼出しがハング・アップしてしまいます。

            // Activate PersistentPOA's POAManager. Without this step,
            // all calls to Persistent Server will hang because POAManager
            // will be in the 'HOLD' state.
            persistentPOA.the_POAManager().activate( );

ステップ5: サーバントの起動

次の説明は、CORBA仕様のセクション11.2.5から引用したものです。

CORBAオブジェクトは、アクティブなサーバントに関連付けられる場合と関連付けられない場合があります。

POAにRETAINポリシーが定義されている場合、サーバントとサーバントに関連付けられているオブジェクトIDが、適切なPOAのアクティブ・オブジェクト・マップに入力されます。このような起動は、次のどれかの方法で実行できます。

USE_DEFAULT_SERVANTポリシーも有効になっている場合、サーバー・アプリケーションは、オブジェクトIDにかかわらず、1つのサーバントを起動することによって未知のオブジェクトを起動するようにPOAに指示します。サーバー・アプリケーションは、set_servantを使用してこのサーバントを登録します。

POAにNON_RETAINポリシーが定義されている場合、POAは、すべての要求に対して、デフォルトのサーバントまたはサーバント・マネージャを使用してアクティブなサーバントを探すことができます。POAから見ると、サーバントは、1つの要求の処理中だけアクティブになっています。POAは、サーバントとオブジェクトの関連付けをアクティブ・オブジェクト・マップに入力しません。

RMI-IIOPテクノロジを使用している実装は、その実装をインタフェースに関連付けるために委譲(「Tieモデル」と呼ばれる)を使用します。実装のインスタンスを作成したときは、そのインスタンスをCORBAインタフェースに関連付けるためにTieオブジェクトを作成する必要もあります。次のコードは、POAポリシーがUSE_ACTIVE_OBJECT_MAP_ONLYの場合にTieを起動する方法を示しています。このサンプル・コードは、RMI-IIOPを使ったPOAの例で使用されているものです。

_HelloImpl_Tie tie = (_HelloImpl_Tie)Util.getTie( helloImpl );
String helloId = "hello";
byte[] id = helloId.getBytes();
tPOA.activate_object_with_id( id, tie );

CORBA仕様には、オブジェクト参照の作成(セクション11.2.4)、オブジェクトの起動(セクション11.2.5)、および要求の処理(セクション11.2.6)に関する詳しい説明が記載されています。詳細は、「CORBA 2.3.1仕様」を参照してください。

ステップ6: オブジェクト参照の作成

オブジェクト参照はサーバーで作成されます。作成したオブジェクト参照はクライアントにエクスポートできます。オブジェクト参照は、オブジェクトの識別情報をカプセル化し、さらにオブジェクトに関連付けられているサーバーとPOAを識別して探すためにORBが必要とする情報をカプセル化します。参照は、次のいくつかの方法で作成されます。

サーバーで作成した参照は、クライアントに提供することができます。オブジェクト参照の作成とクライアントへのエクスポートの詳細については、「CORBA 2.3.1仕様」のセクション11.2.4を参照してください。

アダプタ・アクティベータ

アダプタ・アクティベータはオプションです。アダプタ・アクティベータは、要求の処理中にPOAを作成する必要がある場合に使用します。アプリケーションの実行時に、必要なPOAがすべて作成されている場合は、アダプタ・アクティベータは必要ありません。

アダプタ・アクティベータを使用すると、POAは、必要に応じて子POAを作成できるようになります(子POA (または複数の子のどれか)を指定した要求を受信したときの副作用として、あるいは起動パラメータ値TRUEを使用してfind_POAメソッドが呼び出されたとき)。ORBは、存在していない子POAへの要求を受け取ると、アダプタ・アクティベータのオペレーションを呼び出します。アダプタ・アクティベータは必要なPOAをその場で作成します。

要求は、ターゲット・オブジェクトのオブジェクトIDと、ターゲット・オブジェクト参照を作成したPOAの識別情報を伝達できる必要があります。クライアントから要求が発行されると、ORBは、初めに適切なサーバーを探し(必要な場合は起動する)、次にそのサーバー内で適切なPOAを探します。

サーバー・プロセス内にPOAが存在しない場合、アプリケーションは、アダプタ・アクティベータを使用して必要なPOAを再作成することができます。アダプタ・アクティベータは、ユーザーによって実装されるオブジェクトで、POAに関連付けることができます。アダプタ・アクティベータは、存在していないPOAへの要求を受け取った場合に、ORBによって呼び出されます。ここでアダプタ・アクティベータに、必要なPOAを作成する機会が与えられます。そうしない場合、クライアントはADAPTER_NONEXISTENT例外を受け取ります。

ORBは、必要なPOAを見つけると、そのPOAに要求を渡します。そのあとの要求の処理は、POAに関連付けられているポリシーと、オブジェクトの現在の起動状態によって異なります。

アダプタ・アクティベータの詳細については、CORBA 2.3.1仕様のセクション11.3.3またはAdapterActivatorOperations APIドキュメントを参照してください。

サーバント・マネージャ

サーバント・マネージャはオプションです。サーバント・マネージャを使用すると、POAが、無効なオブジェクトに対する要求を受け取ったときに、必要なサーバントを起動できるようになります。サーバーが起動時にすべてのオブジェクトをロードする場合は、サーバント・マネージャは必要ありません。

サーバント・マネージャは、アプリケーション開発者がPOAと関連付けることができるコールバック・オブジェクトです。ORBはサーバント・マネージャのオペレーションを呼び出して、要求に応じてサーバントを活性化したり非活性化させたりします。サーバント・マネージャには、オブジェクトID値で特徴づけられるオブジェクト参照と特定のサーバントの関連を管理し、オブジェクト参照が存在するかどうかを決定する機能があります。各型のサーバント・マネージャは2つのオペレーションを実行できます。1つはサーバントを見つけて返すためのオペレーションで、もう1つはサーバントを停止するためのオペレーションです。オペレーションは、その状況で使用できる情報の量によって異なります。

サーバント・マネージャを使用するには、USE_SERVANT_MANAGERポリシーを設定する必要があります。このポリシーを設定すると、POA内のほかのポリシーに応じて、特定の状況で使用されるサーバント・マネージャの型が決まります。サーバント・マネージャには次の2つの型があります。

サーバント・マネージャの詳細については、CORBA 2.3.1仕様のセクション11.3.4を参照してください。

POA Q&A

POAを新しく作成する場合にPOAManager.activate()が必要ですか。

POA::createPOAに対するPOAManagerパラメータとしてnullを渡す場合は、新しくPOAを作成するときにPOAManager.activate()が必要です。nullを渡すと、新しいPOAManagerが作成され、作成されるPOAに関連付けられます。この場合は、POAManager.activate()が必要です。

同じPOAManagerを使用して複数のPOAを制御するには、次の手順を実行します。

  1. POAを作成するかまたはrootPOAを使用します。
  2. POA::the_POAManagerを使用してPOAのマネージャを取得します。
  3. そのあとのcreatePOAの呼出しにPOAManagerを渡します。

プログラマが上記のように明示的にプログラミングしないかぎり、ルートPOAのPOAManagerとほかのPOAの間に暗黙的な関係は存在しません。

詳細については、CORBA specification, formal/99-10-07のセクション11.3.2を参照してください。

詳細情報

ポータブル・オブジェクト・アダプタについては、Object Management GroupのサイトにあるCORBA/IIOP v2.3.1仕様の第11章を参照してください。

Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.