このドキュメントでは、IDL から Java 言語へのマッピング仕様に従って IDL-to-Java コンパイラで生成したコード (準拠の詳細については準拠に関するドキュメントを参照) を紹介し、サンプルのクライアントアプリケーションとサーバアプリケーションについて説明します。
ここに記載したコードの詳細な説明については、入門チュートリアル「Java IDL 入門」を参照してください。
次のファイル (Hello.idl) は OMG インタフェース定義言語 (IDL) で記述されたもので、CORBA オブジェクトの sayHello() 操作が文字列 (string) を返し shutdown() メソッドが ORB を停止させています。OMG IDL は、分散型アプリケーションでプログラミング言語に依存しない操作インタフェースを指定するために設計された、純粋な宣言型の言語です。IDL はさまざまなプログラミング言語にマッピングできます。IDL を Java にマッピングする方法は、「IDL と Java 言語のマッピングの概要」で説明しています。
OMG IDL の構文とセマンティクスの詳細は、OMG の Web サイトで CORBA 仕様の第 3 章を参照してください。
Hello.idl
module HelloApp { interface Hello { string sayHello(); oneway void shutdown(); }; };
idlj コンパイラは、IDL-to-Java マッピングを使って IDL インタフェース定義を対応する Java インタフェース、クラス、およびメソッドに変換します。次に、それを使ってクライアントとサーバコードを実装できます。次のファイルは、次のコマンドを使って IDL-to-Java コンパイラで Hello.idl をコンパイルすると生成されます。
idlj -fall Hello.idl
シグニチャーインタフェースファイル Hello.java は、org.omg.portable.IDLEntity、org.omg.CORBA.Object、および操作インタフェース HelloOperations を継承したものです。シグニチャーインタフェースは、指定した型のインタフェースを他のインタフェースで使用する場合にメソッド宣言のシグニチャー型として使用します。クライアントの観点から述べると、CORBA Hello
オブジェクトのオブジェクト参照は、このインタフェースを実装します。
注: スタブは Hello
インタフェースを実装します。ここで各メソッドのコードを生成して引数を整列化してメソッドを呼び出し、引数の整列化を解除します。
package HelloApp; /** * HelloApp/Hello.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl * Thursday, March 22, 2001 2:17:15 PM PST */ public interface Hello extends HelloOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity { } // interface Hello
Java 操作インタフェース HelloOperations.java
はサーバ側のマッピングで使用され、同じ場所にあるクライアントとサーバに最適化された呼び出しを提供する機構として使用されます。サーバの開発者は、操作インタフェースで指示されたメソッドに対して実装を提供します。
このインタフェースには sayHello() メソッドおよび shutdown() メソッドが含まれます。IDL-to-Java マッピングは、IDL インタフェースで定義された操作をすべてこのファイルに組み込み、スタブとスケルトンで共有します。
注: サーバの開発者は、通常、HelloPOA
を拡張し、操作インタフェースで提供されたメソッドに対して実装を提供します。
package HelloApp; /** * HelloApp/HelloOperations.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl * Thursday, March 22, 2001 2:17:15 PM PST */ public interface HelloOperations { String sayHello (); void Shutdown (); } // interface HelloOperations
Java クラス HelloHelper
は補助的な機能を提供します。 特に、CORBA オブジェクト参照を適切な型にキャストするための narrow() メソッドは重要な役割を果たします。ヘルパークラスは、CORBA ストリームへのデータ型の読み書き、および Any からのデータ型の挿入および抽出を担当します。Holder クラスは Helper クラスのメソッドに入出力を委譲します。
package HelloApp; /** * HelloApp/HelloHelper.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl * Thursday, March 22, 2001 2:17:15 PM PST */ abstract public class HelloHelper { private static String _id = "IDL:HelloApp/Hello:1.0"; public static void insert (org.omg.CORBA.Any a, HelloApp.Hello that) { org.omg.CORBA.portable.OutputStream out = a.create_output_stream (); a.type (type ()); write (out, that); a.read_value (out.create_input_stream (), type ()); } public static HelloApp.Hello extract (org.omg.CORBA.Any a) { return read (a.create_input_stream ()); } private static org.omg.CORBA.TypeCode __typeCode = null; synchronized public static org.omg.CORBA.TypeCode type () { if (__typeCode == null) { __typeCode = org.omg.CORBA.ORB.init ().create_interface_tc (HelloApp.HelloHelper.id (), "Hello"); } return __typeCode; } public static String id () { return _id; } public static HelloApp.Hello read (org.omg.CORBA.portable.InputStream istream) { return narrow (istream.read_Object (_HelloStub.class)); } public static void write (org.omg.CORBA.portable.OutputStream ostream, HelloApp.Hello value) { ostream.write_Object ((org.omg.CORBA.Object) value); } public static HelloApp.Hello narrow (org.omg.CORBA.Object obj) { if (obj == null) return null; else if (obj instanceof HelloApp.Hello) return (HelloApp.Hello)obj; else if (!obj._is_a (id ())) throw new org.omg.CORBA.BAD_PARAM (); else { org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate (); HelloApp._HelloStub stub = new HelloApp._HelloStub (); stub._set_delegate(delegate); return stub; } } }
Java クラス HelloHolder には、Hello 型のパブリックインスタンスメンバが入ります。IDL 型のパラメータが out または inout であれば Holder クラスが使用されます。ここでは、org.omg.CORBA.portable.OutputStream および org.omg.CORBA.portable.InputStream 引数に対する操作が規定されます。これらの引数は CORBA には存在しますが、Java のセマンティクスには簡単にマッピングできません。Holder クラスは Helper クラスのメソッドに入出力を委譲します。Holder クラスは org.omg.CORBA.portable.Streamable を実装します。
package HelloApp; /** * HelloApp/HelloHolder.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl * Thursday, March 22, 2001 2:17:15 PM PST */ public final class HelloHolder implements org.omg.CORBA.portable.Streamable { public HelloApp.Hello value = null; public HelloHolder () { } public HelloHolder (HelloApp.Hello initialValue) { value = initialValue; } public void _read (org.omg.CORBA.portable.InputStream i) { value = HelloApp.HelloHelper.read (i); } public void _write (org.omg.CORBA.portable.OutputStream o) { HelloApp.HelloHelper.write (o, value); } public org.omg.CORBA.TypeCode _type () { return HelloApp.HelloHelper.type (); } }
Java クラス _HelloStub は、クライアント側マッピングのスタブファイルです。これは org.omg.CORBA.portable.ObjectImpl を継承し、Hello.java インタフェースを実装します。
package HelloApp; /** * HelloApp/_HelloStub.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl * Thursday, March 22, 2001 2:17:15 PM PST */ public class _HelloStub extends org.omg.CORBA.portable.ObjectImpl implements HelloApp.Hello { public String sayHello () { org.omg.CORBA.portable.InputStream _in = null; try { org.omg.CORBA.portable.OutputStream _out = _request ("sayHello", true); _in = _invoke (_out); String __result = _in.read_string (); return __result; } catch (org.omg.CORBA.portable.ApplicationException _ex) { _in = _ex.getInputStream (); String _id = _ex.getId (); throw new org.omg.CORBA.MARSHAL (_id); } catch (org.omg.CORBA.portable.RemarshalException _rm) { return sayHello (); } finally { _releaseReply (_in); } } // sayHello public void Shutdown () { org.omg.CORBA.portable.InputStream _in = null; try { org.omg.CORBA.portable.OutputStream _out = _request ("Shutdown", false); _in = _invoke (_out); } catch (org.omg.CORBA.portable.ApplicationException _ex) { _in = _ex.getInputStream (); String _id = _ex.getId (); throw new org.omg.CORBA.MARSHAL (_id); } catch (org.omg.CORBA.portable.RemarshalException _rm) { Shutdown (); } finally { _releaseReply (_in); } } // Shutdown // Type-specific CORBA::Object operations private static String[] __ids = { "IDL:HelloApp/Hello:1.0"}; public String[] _ids () { return (String[])__ids.clone (); } private void readObject (java.io.ObjectInputStream s) throws java.io.IOException { String str = s.readUTF (); String[] args = null; java.util.Properties props = null; org.omg.CORBA.Object obj = org.omg.CORBA.ORB.init (args, props).string_to_object (str); org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate (); _set_delegate (delegate); } private void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException { String[] args = null; java.util.Properties props = null; String str = org.omg.CORBA.ORB.init (args, props).object_to_string (this); s.writeUTF (str); } } // class _HelloStub
Java クラス HelloImplPOA はサーバ側のマッピングのスケルトンファイルで、サーバ用に基本的な CORBA 機能を提供します。これは org.omg.PortableServer.Servant を継承し、InvokeHandler インタフェースと HelloOperations インタフェースを実装します。サーバクラスの HelloServant は、HelloPOA を継承します。
package HelloApp; /** * HelloApp/HelloPOA.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl * Thursday, March 22, 2001 2:17:15 PM PST */ public abstract class HelloPOA extends org.omg.PortableServer.Servant implements HelloApp.HelloOperations, org.omg.CORBA.portable.InvokeHandler { // Constructors private static java.util.Hashtable _methods = new java.util.Hashtable (); static { _methods.put ("sayHello", new java.lang.Integer (0)); _methods.put ("Shutdown", new java.lang.Integer (1)); } public org.omg.CORBA.portable.OutputStream _invoke (String method, org.omg.CORBA.portable.InputStream in, org.omg.CORBA.portable.ResponseHandler rh) { org.omg.CORBA.portable.OutputStream out = null; java.lang.Integer __method = (java.lang.Integer)_methods.get (method); if (__method == null) throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE); switch (__method.intValue ()) { case 0: // HelloApp/Hello/sayHello { String __result = null; __result = this.sayHello (); out = rh.createReply(); out.write_string (__result); break; } case 1: // HelloApp/Hello/Shutdown { this.Shutdown (); out = rh.createReply(); break; } default: throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE); } return out; } // _invoke // Type-specific CORBA::Object operations private static String[] __ids = { "IDL:HelloApp/Hello:1.0"}; public String[] _all_interfaces (org.omg.PortableServer.POA poa, byte[] objectId) { return (String[])__ids.clone (); } public Hello _this() { return HelloHelper.narrow( super._this_object()); } public Hello _this(org.omg.CORBA.ORB orb) { return HelloHelper.narrow( super._this_object(orb)); } } // class HelloPOA
アプリケーションを完成させるには、開発者がクライアントとサーバのコードを記述する必要があります。
ここで紹介するサーバは、サーバントとサーバの 2 つのクラスで構成されます。サーバントである HelloImpl は、Hello IDL インタフェースの実装です。つまり、Hello の各インスタンスは、HelloImpl のインスタンスにより実装されます。サーバントは、idlj コンパイラにより例の IDL から生成される HelloPOA のサブクラスです。
サーバントには、IDL 操作ごとに 1 つのメソッドが含まれます。この例では、sayHello() および shutdown() メソッドです。サーバントメソッドは、Java の通常のメソッドと変わりはありません。ORB の処理、引数や結果の整列化などを行うコードは、スケルトンで実装します。
次の例では、一時サーバのコードを示します。持続サーバを使った「Hello World」アプリケーションについては、持続サーバを使った Hello World の例を参照してください。
次のコードは、開発者によって記述されます。
// HelloServer.java // Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.Properties; class HelloImpl extends HelloPOA { private ORB orb; public void setORB(ORB orb_val) { orb = orb_val; } // implement sayHello() method public String sayHello() { return "\nHello world !!\n"; } // implement shutdown() method public void shutdown() { orb.shutdown(false); } } public class HelloServer { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // get reference to rootpoa & activate the POAManager POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); // create servant and register it with the ORB HelloImpl helloImpl = new HelloImpl(); helloImpl.setORB(orb); // get object reference from the servant org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl); Hello href = HelloHelper.narrow(ref); // get the root naming context // NameService invokes the name service org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); // Use NamingContextExt which is part of the Interoperable // Naming Service (INS) specification. NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); // bind the Object Reference in Naming String name = "Hello"; NameComponent path[] = ncRef.to_name( name ); ncRef.rebind(path, href); System.out.println("HelloServer ready and waiting ..."); // wait for invocations from clients orb.run(); } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } System.out.println("HelloServer Exiting ..."); } }
次の例では、Java クライアントアプリケーションを示します。CORBA クライアントは、サーブレット、JSP、アプレットなどとして記述できます。
// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; public class HelloClient { static Hello helloImpl; public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); // Use NamingContextExt instead of NamingContext. This is // part of the Interoperable naming Service. NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); // resolve the Object Reference in Naming String name = "Hello"; helloImpl = HelloHelper.narrow(ncRef.resolve_str(name)); System.out.println("Obtained a handle on server object: " + helloImpl); System.out.println(helloImpl.sayHello()); helloImpl.shutdown(); } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } }
Java CORBA アプリケーションのコンパイルと実行の詳細については、「Hello World の構築方法と実行方法」を参照してください。
Copyright © 2001-2004 Sun Microsystems, Inc.All Rights Reserved.
|
Java ソフトウェア |