|
このドキュメントでは、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 ソフトウェア |