アプリケーション開発者は、新しい POA を作成するときに、新しい POA 用に選択した特定のポリシーを宣言し、異なるアダプタアクティベータおよびサーバントマネージャー (これらは、必要時の POA の起動とサーバントの起動を行うために POA が使用するコールバックオブジェクト) を提供できます。オブジェクト ID は POA に対して相対的に解釈されるため、アプリケーション開発者は、新しい POA を作成することによってさらにオブジェクトの名前空間の区分けも行うことができます。また、新しい POA を作成すると、開発者は、複数のオブジェクトのセットに対する要求の処理を個別に制御できます。
サーバントアクティベータは、サーバントマネージャーの 1 つの型です。サーバントマネージャーはオプションです。サーバントマネージャーを使用すると、POA が、無効なオブジェクトに対する要求を受け取ったときに、必要なサーバントを起動できるようになります。サーバーが起動時にすべてのオブジェクトをロードする場合は、サーバントマネージャーは必要ありません。
サーバントマネージャーは、アプリケーション開発者が POA と関連付けることができるコールバックオブジェクトです。ORB はサーバントマネージャーのオペレーションを呼び出して、要求に応じてサーバントを活性化したり非活性化させたりします。サーバントマネージャーには、オブジェクト ID 値で特徴づけられるオブジェクト参照と特定のサーバントの関連を管理し、オブジェクト参照が存在するかどうかを決定する機能があります。各型のサーバントマネージャーは 2 つのオペレーションを実行できます。1 つはサーバントを見つけて返すためのオペレーションで、もう 1 つはサーバントを停止するためのオペレーションです。オペレーションは、その状況で使用できる情報の量によって異なります。
サーバントマネージャーを使用するには、USE_SERVANT_MANAGER
ポリシーを設定する必要があります。このポリシーを設定すると、POA 内のほかのポリシーに応じて、特定の状況で使用されるサーバントマネージャーの型が決まります。サーバントマネージャーには次の 2 つの型があります。
ServantActivator
RETAIN
ポリシーを持つ POA は、ServantActivators
であるサーバントマネージャーを使用します。ServantActivator
では常に、アクティブオブジェクトマップにエントリが生成されます。サーバントはその後、停止するまでそのエントリを使用します。サーバントを停止するには、POA、POA マネージャー、または ORB を破棄するか、明示的に deactivate
を呼び出します。
ServantLocator
NON_RETAIN
ポリシーを持つ POA は、ServantLocators
であるサーバントマネージャーを使用します。POA は、このサーバントマネージャーによって返されるサーバントが単一の要求の処理にだけ使用されることを認識しているため、サーバントマネージャーのオペレーションに追加の情報を提供でき、サーバントマネージャーのオペレーションペアを連携させて ServantActivator
とは異なる処理を実行できます。POA が ServantLocator
インタフェースを使用する場合、preinvoke によって返されたサーバントの呼び出しオペレーションを実行した直後に、POA は、サーバントマネージャーの postinvoke を呼び出し、ObjectId 値および Servant 値をパラメータの一部として渡します。この機能は、POA に関連付けられたオブジェクトの各要求が強制的にサーバントマネージャーを介して行われるようにする場合に使用されます。
次のコードは、POA が一時オブジェクトを起動できるようにするために、サーバントロケータを使用するアプリケーションの例を示しています。このアプリケーションは、「Hello World」の例を基にして作成したものです。参考用に、次のファイルが含まれています。
import org.omg.CORBA.ORB; import org.omg.CosNaming.*; public class Client { public Client(String[] args) { try { ORB orb = ORB.init(args, System.getProperties()); NamingContext rootContext = NamingContextHelper.narrow( orb.resolve_initial_references("NameService")); // Resolves for remote object reference of HelloServer NameComponent name[] = {new NameComponent("HelloServer", "")}; Hello helloRef = HelloHelper.narrow(rootContext.resolve(name)); System.out.println("\nClient: Obtained the remote object " + "reference"); // Invokes the remote sayHello() method System.out.println("Client: Invoking the remote operation ..."); System.out.println(helloRef.sayHello()); } catch (Exception e) { System.err.println("\nClient: Caught exception - " + e); e.printStackTrace(); } } public static void main(String [] args) { Client servantLocatorClient = new Client(args); } }
import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.ServantLocatorPackage.*; import org.omg.CosNaming.*; public class Server { public Server(String[] args) { try { ORB orb = ORB.init(args, System.getProperties()); POA rootPoa = (POA) orb.resolve_initial_references("RootPOA"); rootPoa.the_POAManager().activate(); System.out.println("\nServer: Obtained from ORB and activated " + "the " + rootPoa.the_name()); Policy poaPolicy[] = new Policy[2]; poaPolicy[0] = rootPoa.create_servant_retention_policy( ServantRetentionPolicyValue.NON_RETAIN); poaPolicy[1] = rootPoa.create_request_processing_policy( RequestProcessingPolicyValue.USE_SERVANT_MANAGER); System.out.println("Server: Set POA policy as NON_RETAIN and " + "USE_SERVANT_MANAGER"); POA poa1 = rootPoa.create_POA("HelloPoa", null, poaPolicy); poa1.the_POAManager().activate(); System.out.println("Server: Created and activated child POA " + "\"" + poa1.the_name() + "\""); poa1.set_servant_manager(new PoaServantLocator()); System.out.println("Server: Associated the servant manager of " + "type servant locator with \"" + poa1.the_name() + "\""); // This create_reference operation does not cause an activation, // the resulting object reference will be exported and passed to // client, so that subsequent requests on the reference will cause // the appropriate servant manager to be invoked org.omg.CORBA.Object objectRef = poa1.create_reference( HelloHelper.id()); System.out.println("Server: Created a CORBA object reference " + "from id \"" + HelloHelper.id() + "\""); NamingContext rootContext = NamingContextHelper.narrow( orb.resolve_initial_references("NameService")); NameComponent name[] = {new NameComponent("HelloServer", "")}; rootContext.rebind(name, objectRef); System.out.println("Server: Exported the CORBA object reference " + "to NameService"); System.out.println("Server: Ready and waiting for requests ..."); orb.run(); } catch (Exception e) { System.err.println("\nServer: Caught exception - " + e); e.printStackTrace(); } } public static void main(String [] args) { Server serverServantLocator = new Server(args) ; } } class PoaServantLocator extends LocalObject implements ServantLocator { public Servant preinvoke(byte[] oid, POA adapter, String operation, CookieHolder the_cookie) throws ForwardRequest { try { HelloImpl servantObj = new HelloImpl(); System.out.println("PoaServantLocator.preinvoke(): Created \"" + servantObj.getClass().getName() + "\" " + "servant object for \"" + adapter.the_name() + "\""); return servantObj; } catch (Exception e) { System.err.println("preinvoke: Caught exception - " + e); } return null; } public void postinvoke(byte[] oid, POA adapter, String operation, java.lang.Object the_cookie, Servant the_servant) { try { System.out.println("PoaServantLocator.postinvoke(): For \"" + adapter.the_name() + "\" adapter of servant " + "object type \"" + the_servant.getClass().getName() + "\""); } catch (Exception e) { System.err.println("postinvoke: Caught exception - " + e); } } }
interface Hello { string sayHello(); };
public class HelloImpl extends HelloPOA { public String sayHello() { return "Hello :)"; } }
IDLJ=${JAVA_HOME}/bin/idlj JAVAC=${JAVA_HOME}/bin/javac JAVA=${JAVA_HOME}/bin/java CLASSFILES=./classes_dir IDLJFLAGS=-fall -verbose -td ${CLASSFILES} JFLAGS=-g -d $(CLASSFILES) -classpath $(CLASSFILES) JAVAFLAGS=-cp $(CLASSFILES) -Dorg.omg.CORBA.ORBInitialHost=localhost \ -Dorg.omg.CORBA.ORBInitialPort=1950 ORBD_FLAGS=-port 1949 -ORBInitialHost ${SERVER_HOSTNAME} \ -ORBInitialPort 1950 -ORBDebug ORBD=${JAVA_HOME}/bin/orbd $(ORBD_FLAGS) orbd client = Client.java server = HelloImpl.java \ Server.java all: clean build run clean: @echo "" @echo "*** Clean up old files and directories ***" -$(RM) $(CLASSFILES) -$(RM) ./orb.db -$(RM) ./kill_started_processes.sh build: stubs client_server stubs: Hello.idl @echo "" @echo "*** Generate stubs and helpers ***" @-$(MKDIR) $(CLASSFILES) $(IDLJ) $(IDLJFLAGS) Hello.idl client_server: $(client) $(server) @echo "" @echo "*** Compile client, server and implementation ***" $(JAVAC) $(JFLAGS) $(client) $(server) run: run_orbd run_server run_client terminate_servers run_orbd: @echo "" @echo "*** Start the orbd ***" $(ORBD) & \ echo "kill -9 $$!" > ./kill_started_processes.sh; \ if [ $(OS) = "WinNT" ] ; then \ tpid=`ps -o pid,ppid,comm | grep $$! | grep -v "sh" | cut -c1-6` ; \ echo "kill -9 $$tpid" >> ./kill_started_processes.sh ; \ fi ; \ $(SLEEP) $(SLEEP_LONG) run_server: run_orbd @echo "" @echo "*** Start the Server ***" $(JAVA) $(JAVAFLAGS) Server & \ echo "kill -9 $$!" >> ./kill_started_processes.sh; \ if [ $(OS) = "WinNT" ] ; then \ tpid=`ps -o pid,ppid,comm | grep $$! | grep -v "sh" | cut -c1-6` ; \ echo "kill -9 $$tpid" >> ./kill_started_processes.sh ; \ fi ; \ $(SLEEP) $(SLEEP_NORMAL) run_client: @echo "" @echo "*** Start the Client ***" $(JAVA) $(JAVAFLAGS) Client terminate_servers: @echo "" @echo "*** Terminate the Server and orbd ***" @$(SLEEP) $(SLEEP_SHORT) @if [ -f ./kill_started_processes.sh ]; then \ $(CHMOD) u+x ./kill_started_processes.sh; \ ./kill_started_processes.sh; \ $(SLEEP) $(SLEEP_SHORT) ; \ fi
#!/bin/ksh if [ `uname` = "SunOS" ] ; then OS="Solaris_sparc" JAVA_HOME=/path_to_your_java_installation SEP=: SLEEP=/bin/sleep RM="/bin/rm -rf" CHMOD=/bin/chmod MKDIR=/bin/mkdir SLEEP_SHORT=2 SLEEP_NORMAL=5 SLEEP_LONG=7 elif [ `uname` = "Windows_NT" ] ; then OS="WinNT" if [ ! -d "y:/path_to_your_java_installation" ] ; then echo; echo "Please map drive y: to \\\\\path_to_your_java_installation before runSample" exit 1 fi JAVA_HOME="y:/path_to_your_java_installation" SEP=";" SLEEP=sleep RM="rm -rf" CHMOD=chmod MKDIR="mkdir -p" SLEEP_SHORT=5 SLEEP_NORMAL=10 SLEEP_LONG=15 fi while [ $# -gt 0 ] ; do case $1 in -host ) SERVER_HOSTNAME=$2 ; shift;; * ) TARGET=$* ; break ;; esac shift done DEFAULT_HOSTNAME=localhost SERVER_HOSTNAME=${HOSTNAME-$DEFAULT_HOSTNAME} make ${TARGET} \ "OS=${OS}" \ "JAVA_HOME=${JAVA_HOME}" \ "SERVER_HOSTNAME=${SERVER_HOSTNAME}" \ "SLEEP=${SLEEP}" \ "RM=${RM}" \ "CHMOD=${CHMOD}" \ "MKDIR=${MKDIR}" \ "SLEEP_SHORT=${SLEEP_SHORT}" \ "SLEEP_NORMAL=${SLEEP_NORMAL}" \ "SLEEP_LONG=${SLEEP_LONG}"
この例を実行するには、次のようにします。
runSample
に示されているとおりに、例を実行します。端末ウィンドウに次の例のような出力が表示されます。
*** Clean up old files and directories *** /bin/rm -rf ./classes_dir /bin/rm -rf ./orb.db /bin/rm -rf ./kill_started_processes.sh *** Generate stubs and helpers *** /path_to_your_java_installation/bin/idlj -fall -verbose -td ./classes_dir Hello.idl Parsing Hello.idl done - Hello.idl Generating Hello done - Hello *** Compile client, server and implementation *** /path_to_your_java_installation/bin/javac -g -d ./classes_dir -classpath ./classes_dir Client.java HelloImpl.java Server.java *** Start the orbd *** /path_to_your_java_installation/bin/orbd -port 1949 -ORBInitialHost localhost -ORBInitialPort 1950 -ORBDebug orbd & \ echo "kill -9 $!" > ./kill_started_processes.sh; \ if [ Solaris_sparc = "WinNT" ] ; then \ tpid=`ps -o pid,ppid,comm | grep $! | grep -v "sh" | cut -c1-6` ; \ echo "kill -9 $tpid" >> ./kill_started_processes.sh ; \ fi ; \ /bin/sleep 7 ORBD begins initialization. ORBD is ready. ORBD serverid: 1 activation dbdir: /home/dcarson1/samples/POA_samples/ServantLocator/./orb.db activation port: 1949 activation Server Polling Time: 1000 milli-seconds activation Server Startup Delay: 1000 milli-seconds *** Start the Server *** /path_to_your_java_installation/bin/java -cp ./classes_dir -Dorg.omg.CORBA.ORBInitialHost=localhost -Dorg.omg.CORBA.ORBInitialPort=1950 Server & \ echo "kill -9 $!" >> ./kill_started_processes.sh; \ if [ Solaris_sparc = "WinNT" ] ; then \ tpid=`ps -o pid,ppid,comm | grep $! | grep -v "sh" | cut -c1-6` ; \ echo "kill -9 $tpid" >> ./kill_started_processes.sh ; \ fi ; \ /bin/sleep 5 Server: Obtained from ORB and activated the RootPOA Server: Set POA policy as NON_RETAIN and USE_SERVANT_MANAGER Server: Created and activated child POA "HelloPoa" Server: Associated the servant manager of type servant locator with "HelloPoa" Server: Created a CORBA object reference from id "IDL:Hello:1.0" Server: Exported the CORBA object reference to NameService Server: Ready and waiting for requests ... *** Start the Client *** /path_to_your_java_installation/bin/java -cp ./classes_dir -Dorg.omg.CORBA.ORBInitialHost=localhost -Dorg.omg.CORBA.ORBInitialPort=1950 Client Client: Obtained the remote object reference Client: Invoking the remote operation ... PoaServantLocator.preinvoke(): Created "HelloImpl" servant object for "HelloPoa" PoaServantLocator.postinvoke(): For "HelloPoa" adapter of servant object type "HelloImpl" Hello :) *** Terminate the Server and orbd ***
サーバントロケータの詳細については、CORBA 2.3.1 仕様のサーバントマネージャーに関するセクション (セクション 11.3.4) を参照してください。