このドキュメントでは、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 の構文とセマンティクスの詳細は、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() メソッドは重要な役割を果たします。Helper クラスは、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 型の public インスタンスメンバーが入ります。IDL 型のパラメータが out または inout であれば Holder クラスが使用されます。これは、org.omg.CORBA.portable.OutputStream および org.omg.CORBA.portable.InputStream 引数 (CORBA は許可しますが、Java のセマンティクスには簡単にマッピングできません) に対するオペレーションを提供します。Holder クラスは Helper クラスのメソッドに入出力を委譲します。これは org.omg.CORBA.portable.Streamable を実装します。
HelloApp/HelloHolder.javapackage 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 インタフェースを実装します。
HelloApp/_HelloStub.javapackage 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 を拡張します。
HelloApp/HelloPOA.javapackage 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// 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、アプレットなどとして記述できます。
HelloClient.java// 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 の構築方法と実行方法」を参照してください。