アダプタ・アクティベータの使用

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

アダプタ・アクティベータはオプションです。アダプタ・アクティベータは、要求の処理中に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に関連付けられているポリシーと、オブジェクトの現在の起動状態によって異なります。

アダプタ・アクティベータの使用例

次のコードは、要求の処理中にPOAを作成できるようにするためにアダプタ・アクティベータを使用するアプリケーションの例を示しています。このアプリケーションは、「Hello World」の例を基にして作成したものです。この例には次のファイルが含まれています。

この例を実行する方法については、「アダプタ・アクティベータのアプリケーション例の実行」を参照してください。

Client.java

サンプル・クライアントのためのコードで、ORBを初期化し、HelloServantを解決し、sayHello()メソッドを呼び出します。

//Client.java
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextHelper;
import org.omg.CosNaming.NameComponent;

public class Client {

    public void run(String[] args) {
        try {
            //initialize the orb
            ORB orb = ORB.init(args, null);
            System.out.println("ORB initialized");

            NamingContext namingContext = NamingContextHelper.narrow(
                orb.resolve_initial_references("NameService"));
            NameComponent[] nc = { new NameComponent("HelloServer", "") };

            //resolve HelloServant and invoke sayHello()
            Hello helloRef = HelloHelper.narrow(namingContext.resolve(nc));
            System.out.println("Resolved HelloServant");

            System.out.println(helloRef.sayHello());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Client().run(args);
    }
}

Server.java

サーバーのためのコードで、次のような処理を行います。

//Server.java
import org.omg.CORBA.ORB;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.Policy;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.AdapterActivator;
import org.omg.PortableServer.IdAssignmentPolicyValue;
import org.omg.PortableServer.LifespanPolicyValue;
import org.omg.PortableServer.ImplicitActivationPolicyValue;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextHelper;
import org.omg.CosNaming.NameComponent;

public class Server {

    public void run(String[] args) {
        try {
            //initialize the orb
            ORB orb = ORB.init(args, null);
            System.out.println("ORB initialized");

            //resolve RootPOA
            POA rootPOA = POAHelper.narrow(
                orb.resolve_initial_references("RootPOA"));

            //register adapter activator with rootPOA so that child POAs can
            //be created on demand
            rootPOA.the_activator(new MyAdapterActivator());

            //find_POA with an activate parameter TRUE would cause the
            //adapter activator associated with rootPOA to be invoked if
            //'HelloPOA' does not exist
            POA childPOA = rootPOA.find_POA("HelloPOA", true);

            //Create the object reference for HelloServant
            //and register with naming service
            org.omg.CORBA.Object obj = childPOA.id_to_reference(
                "abcd".getBytes());
            Hello helloRef = HelloHelper.narrow(obj);

            NamingContext namingContext = NamingContextHelper.narrow(
                orb.resolve_initial_references("NameService"));
            NameComponent[] nc = { new NameComponent("HelloServer", "") };
            namingContext.rebind(nc, helloRef);

            //Destroy 'HelloPOA'. This POA will be transparently recreated when
            //ORB receives a request on HelloPOA using the adapter activator we
            //registered with the RootPOA
            childPOA.destroy(true, true);

            //activate rootPOA
            rootPOA.the_POAManager().activate();

            //wait for incoming requests
            System.out.println("Server ready and running....");
            orb.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Server().run(args);
    }
}

class MyAdapterActivator extends LocalObject implements AdapterActivator {

    public boolean unknown_adapter(POA parent, String name) {
        System.out.println("unknown_adapter() invoked for POA - " + name);
        try {
            // create the POA with appropriate policies
            // this sample uses PERSISTENT, NO_IMPLICIT_ACTIVATION
            // and USER_ID policies
            Policy[] policy = new Policy[3];
            policy[0] = parent.create_lifespan_policy(
                LifespanPolicyValue.PERSISTENT);
            policy[1] = parent.create_id_assignment_policy(
                IdAssignmentPolicyValue.USER_ID);
            policy[2] = parent.create_implicit_activation_policy(
                ImplicitActivationPolicyValue.NO_IMPLICIT_ACTIVATION);

            POA child = parent.create_POA(name, null, policy);

            //Associate the servant with the new POA
            HelloServant hello = new HelloServant();
            child.activate_object_with_id("abcd".getBytes(), hello);

            //activate the new POA
            child.the_POAManager().activate();

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

Hello.idl

このインタフェース定義言語(IDL)ファイルは、このサイト上の「Hello World」サンプルのすべてのバリエーションで使用されます。このIDLファイルが記述しているCORBAオブジェクトのsayHello()操作が文字列を返します。
interface Hello { string sayHello(); }; 

HelloServant.java

このサーバントは、Hello IDLインタフェースを実装したものです。Helloの各インスタンスは、HelloServantのインスタンスにより実装されます。サーバントは、idljコンパイラにより例のIDLから生成されるHelloPOAのサブクラスです。サーバントには、IDL操作ごとに1つのメソッドが含まれます。この例では、sayHello()メソッドです。サーバント・メソッドは、Javaの通常のメソッドと変わりはありません。ORBの処理、引数や結果の整列化などを行うコードは、スケルトンで実装します。
//HelloServant.java
public class HelloServant extends HelloPOA {

    public String sayHello() {
        return "Hello :)";
    }
}

Makefile

makeプログラムは、Solaris、LinuxまたはMac OS Xのシェルが実行する一連のコマンドを生成します。

JAVA_HOME=<path_to_your_Java_installation_bin_directory>

#setup tools
JAVA=$(JAVA_HOME)/bin/java
JAVAC=$(JAVA_HOME)/bin/javac
IDLJ=$(JAVA_HOME)/bin/idlj
ORBD=$(JAVA_HOME)/bin/orbd

all     : clean build run

clean   :
        - rm -rf classes orb.db

build   :
        mkdir -p classes
        $(IDLJ) -fall -td classes Hello.idl
        $(JAVAC) -classpath classes -d classes HelloServant.java Server.java Client.java

run     : runorbd register runclient

runorbd :
        $(ORBD) -ORBInitialPort 10001 &
        sleep 20

register:
        #servertool does not support script based register due to a bug
        #using class instead
        #Please note that the name of the servertool 
        #class may change in future releases.
        $(JAVA) com.sun.corba.se.internal.Activation.ServerTool \
        -ORBInitialPort 10001 -cmd \
        register -server Server -classpath classes

runclient :
        $(JAVA) -classpath classes Client -ORBInitialPort 10001


run.bat

batユーティリティは、Microsoft Windowsのコマンド・シェルが実行する一連のコマンドを生成します。

SET JAVA_HOME=<path_to_your_Java_installation_build_directory>

mkdir classes

%JAVA_HOME%\bin\idlj -fall -td classes Hello.idl
%JAVA_HOME%\bin\javac -classpath classes -d classes HelloServant.java Server.java Client.java

REM - Start the ORB daemon

start %JAVA_HOME%\bin\orbd -ORBInitialPort 10001 -ORBDebug orbd
@echo Wait 10-15 seconds for the orbd to start
@pause

REM - Register the persistent server with orbd using servertool
REM - Please note that the name of the servertool 
REM - class may change in future releases.
%JAVA_HOME%\bin\java com.sun.corba.se.internal.Activation.ServerTool -ORBInitialPort 10001 -cmd register -server Server -classpath classes

%JAVA_HOME%\bin\java -classpath classes Client -ORBInitialPort 10001

アダプタ・アクティベータのアプリケーション例の実行

この例を実行するには、次のようにします。

Makefileを実行すると、端末ウィンドウに次の例のような出力が表示されます。

rm -rf classes orb.db mkdir -p classes /j2sdk1.5.0/bin/idlj -fall -td classes Hello.idl /j2sdk1.5.0/bin/javac -classpath classes -d classes HelloServant.java Server.java Client.java /j2sdk1.5.0/bin/orbd -ORBInitialPort 10001 & sleep 20 #servertool does not support script based register due to a bug #using class instead #Please note that the name of the servertool 
#class may change in future releases.
/j2sdk1.5.0/bin/java com.sun.corba.se.internal.Activation.ServerTool \
-ORBInitialPort 10001 -cmd \
register -server Server -classpath classes

        server registered (serverid = 257).

/j2sdk1.5.0/bin/java -classpath classes Client -ORBInitialPort 10001
ORB initialized
Resolved HelloServant
Hello :)
この例を実行し終えたら、ORBDをシャットダウンします。

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