WebOTX Manual V11.1 (第6版) 目次を表示 |
Caution
org.omg.CORBA.ORBClassおよびorg.omg.CORBA.ORBSingletonClassはJavaシステムプロパティに指定する方法で設定してください。それ以外の設定方法では有効になりません。
> java <APのクラス名> -CorbalocAskWithMT true -CodeSetEncoding OSF_SJIS1=MS932
-CorbalocAskWithMT=true -CodeSetEncoding=OSF_SJIS1=MS932作成したプロパティ定義ファイルの名前を次のように指定します。
> java <APのクラス名> -PropertyFile <プロパティ定義ファイル名>
: : java.util.Properties props = new java.util.Properties(); props.setProperty("CorbalocAskWithMT", "true"); props.setProperty("CodeSetEncoding", "OSF_SJIS1=MS932"); ORB orb = ORB.init(args, props); : :
> java -Djp.co.nec.orb.CorbalocAskWithMT=true <APのクラス名>
Caution
統合運用管理ツール、運用管理コマンドでの指定は、Standard-J/Standard/Enterpriseの各エディションで、EJBもしくはCORBAのサーバ上でのみ有効になります。
CorbalocAskWithMT=true CodeSetEncoding=OSF_SJIS1=MS932
CorbalocAskWithMT=true CodeSetEncoding=OSF_SJIS1=MS932
: : jp.co.nec.orb.Config.corbalocAskWithMT(); jp.co.nec.orb.Config.setCodeSetEncoding("OSF_SJIS1", "MS932"); : ORB orb = ORB.init(args, props); // ORB初期化 : :
Caution
org.omg.CORBA.ORBClassおよびorg.omg.CORBA.ORBSingletonClassはHTMLのPARAMタグに記述する方法で設定してください。それ以外の設定方法では有効になりません。
<HTML> : <param name="jp.co.nec.orb.CorbalocAskWithMT" value="true"> <param name="jp.co.nec.orb.CodeSetEncoding" value="OSF_SJIS1=MS932"> : </HTML>
: : java.util.Properties props = new java.util.Properties(); props.setProperty("CorbalocAskWithMT", "true"); props.setProperty("CodeSetEncoding", "OSF_SJIS1=MS932"); : ORB orb = ORB.init(applet, props); : :
: : jp.co.nec.orb.Config.corbalocAskWithMT(); jp.co.nec.orb.Config.setCodeSetEncoding("OSF_SJIS1", "MS932"); : ORB orb = ORB.init(applet, props); : :
Caution
タイムアウト時間の既定値は、WebOTX
Ver6.1から30秒に変更になりました。WebOTX
Ver5およびそれ以前のバージョンでは、無制限(タイムアウトしない)が既定値です。
// タイムアウトを10秒に設定 jp.co.nec.orb.Config.setTimeout(10000);
// Helloインタフェースのタイムアウトを10秒に設定 jp.co.nec.orb.Config.setTimeout("Hello", 10000);
// CORBAオブジェクトのタイムアウトを10秒に設定 org.omg.CORBA.Object obj = .... jp.co.nec.orb.Config.setTimeout(obj, 10000);
フックの登録
フックは、jp.co.nec.orb.HookObjクラスを継承して、メソッドをオーバーライドすることで実装します。フックの登録は、フックの実装クラス(HookObj)の次のメソッドを呼び出します。登録後に呼び出しが実行されると、オーバーライドしたメソッドがコールバックされます。フックの削除
フックの削除は、フックの実装クラス(HookObj)の次のメソッドを呼び出します。パラメータレベルのフック
パラメータレベルのフックには、次の4ヶ所のコールバックポイントがあります。各コールバックメソッドがオーバーライドされていれば、各ポイントで呼び出されます。
Caution
パラメータレベルのフックは、スタブ/スケルトンがDSI/DIIで生成された場合のみ使用することができます。スタブ/スケルトンをDSI/DIIで生成するには、IDLコンパイラに-notstreamを指定する必要があります。DSI/DIIでない場合、フックを登録してもエラーになりませんが、コールバックは呼び出されません。
Caution
ServerAfterReceiveでは、ServerRequestクラスのメソッドで最初に値を取得する時に、引数、コンテキストの順で値を取得しなければなりません。
メッセージレベルのフック
メッセージレベルのフックには、次の4ヶ所のコールバックポイントがあります。各コールバックメソッドがオーバーライドされていれば、各ポイントで呼び出されます。
Caution
ServerAfterReceive、ClientAfterReceiveでは、引数のMessageBufferクラスが保持するバッファのサイズはメッセージサイズに関係なく一定です。メッセージがフラグメントで分割されていてメッセージサイズがバッファサイズより長い場合は、メッセージの先頭からバッファサイズ分までが渡されます。
Caution
動的スケルトンインタフェース(DSI)の場合、サーバ側のフックは使用できません。
パラメータレベル | メッセージレベル | |||||||
A | B | C | D | E | F | G | H | |
システムレベル | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
インタフェースレベル | - | ○ | ○ | - | - | - | - | - |
オブジェクトレベル | ○ | ○ | ○ | ○ | ○ | - | - | ○ |
戻り値によるフック実行の制御
フックは、オブジェクトレベル、インタフェースレベル、システムレベルの順に実行されます。また、同じレベルで登録されたフックは、登録された順番で実行されます。メソッドの戻り値によって、処理の中断やスキップを行うことができます。フックを作成するときには、戻り値に注意しなければなりません。 戻り値による制御は次の通りです。
Caution
戻り値で3を指定できるのはパラメータレベルのフックのA,Bの場合だけです。これ以外のメソッドで戻り値に3を指定すると、フック処理を中断します。
リポジトリオブジェクトの取得
インタフェースリポジトリは、リポジトリオブジェクトを頂点とする階層構造をしています。インタフェースリポジトリを利用するには、まず、リポジトリオブジェクトのオブジェクトリファレンスを取得する必要があります。import org.omg.CORBA.*; public class MyProg { public static void main(String args[]) { ORB orbobj = ORB.init(args, null); org.omg.CORBA.Object ir_in_obj = orbobj.resolve_initial_references("InterfaceRepository"); Repository repository = RepositoryHelper.narrow(ir_in_obj); : : } }
インタフェース情報の取得
あるオブジェクトが内包しているオブジェクトの一覧を返すものや、内包しているオブジェクトから手がかりになる文字列を使って検索するものなどさまざまな取得方法があります。 ここでは、org.omg.CORBA.Container.describe_contentsとorg.omg.CORBA.InterfaceDef.describe_interfaceの例を示します。を参照してください。 次のIDL定義がinstifコマンドによりインタフェースリポジトリに登録されているものとします。interface myintf { void op(in short i); };このデータをインタフェースリポジトリから取り出す例を以下に示します。なお、例外処理や複数のインタフェースやオペレーションが含まれていた場合の考慮などは省略します。
import org.omg.CosNaming.*; import org.omg.CORBA.*; public class client { public static void main(String args[]) { //引数モード別 final String[] opemode = { "in", "out", "inout" }; //型別 final String[] tckind = { "null", "void", "short", "long", "ushort", "ulong", "float", "double", "boolean", "char", "octet", "any", "TypeCode", "Principal", "object", "struct", "union", "enum", "string", "sequence", "array", "typedef", "exception", "longlong", "ulonglong", "longdouble", "wchar", "wstring", "fixed", "value", "value_box", "native", "abstract", 0 }; try { // 初期化 ORB orbobj = ORB.init(args, null); // リポジトリオブジェクトの取り出し org.omg.CORBA.Object ir_in_obj = orbobj.resolve_initial_references( "InterfaceRepository"); Repository repository = RepositoryHelper.narrow(ir_in_obj); // リポジトリオブジェクトから // InterfaceDefオブジェクトだけを取り出す // CORBA_dk_Interface : 取り出すのはインタフェースのみ // true :継承されたオブジェクトは含まない //-1 : 数量制限なし org.omg.CORBA.ContainerPackage.Description descseq[] = repository.describe_contents( DefinitionKind.dk_Interface, true, -1); // シーケンスの最初のオブジェクトをnarrowする InterfaceDef intfobj = InterfaceDefHelper.narrow( descseq[0].contained_object); // インタフェース情報を取り出す org.omg.CORBA.InterfaceDefPackage.FullInterfaceDescription intfdesc = intfobj.describe_interface(); // インタフェース名 System.out.println("interface " + intfdesc.name + "{"); // オペレーションのシーケンスから1つ取り出す OperationDescription opedesc = intfdesc.operations[0]; // オペレーションのモード if(opedesc.mode == OperationMode.OP_ONEWAY) System.out.println(" oneway "); // パラメータのシーケンスから1つ取り出す ParameterDescription paradesc = opedesc.parameters[0]; // 戻り値の型, オペレーション名, 引数のモード, 引数を表示 System.out.println(" " + tckind[opedesc.result.kind().value()] + " " + opedesc.name + "(" + opemode[paradesc.mode.value()] + " " + tckind[paradesc.type.kind().value()] + " " + paradesc.name + ")"); System.out.println("};"); } catch(Exception e) { System.out.println("ERROR : " + e); } } }org.omg.CORBA.Container.describe_contents()は、そのオブジェクトが内包しているオブジェクトの一覧をorg.omg.CORBA.ContainerPackage.Descriptionの配列で返します。上記の例ではInterfaceDefに限定して検索をしています。 org.omg.CORBA.ContainerPackage.Descriptionクラスの定義は以下のとおりです。
package org.omg.CORBA.ContainerPackage; final public class Description { // instance variables public org.omg.CORBA.Contained contained_object; public org.omg.CORBA.DefinitionKind kind; public org.omg.CORBA.Any value; // constructors public Description( org.omg.CORBA.Contained _contained_object, org.omg.CORBA.DefinitionKind _kind, org.omg.CORBA.Any_value ) { contained_object = _contained_object; kind = _kind; value = _value; } public Description() {} }contained_objectにはInterfaceDefオブジェクトが入っています。そこで、org.omg.CORBA.InterfaceDef.describe_interface()を使って、そのorg.omg.CORBA.InterfaceDefオブジェクトが内包しているオペレーションのリストを取り出します。オペレーションのリストはorg.omg.CORBA.InterfaceDefPackage.FullInterfaceDescriptionとして返されます。 org.omg.CORBA.InterfaceDefPackage.FullInterfaceDescriptionクラスの定義は以下のとおりです。
package org.omg.CORBA.InterfaceDefPackage; final public class FullInterfaceDescription { // instance variables public java.lang.String name; public java.lang.String id; public java.lang.String defined_in; public java.lang.String version; public org.omg.CORBA.OperationDescription[] operations; public org.omg.CORBA.AttributeDescription[] attributes; public java.lang.String[] base_interfaces; public org.omg.CORBA.TypeCode type; public boolean is_abstract; // constructors public FullInterfaceDescription( java.lang.String _name, java.lang.String _id, java.lang.String _defined_in, java.lang.String _version, org.omg.CORBA.OperationDescription[] _operations, org.omg.CORBA.AttributeDescription[] _attributes, java.lang.String[] _base_interfaces, org.omg.CORBA.TypeCode _type, boolean _is_abstract ) { name = _name; id = _id; defined_in = _defined_in; version = _version; operations = _operations; attributes = _attributes; base_interfaces = _base_interfaces; type = _type; is_abstract = _is_abstract; } public FullInterfaceDescription() {} }さらに、operationsから目的のオペレーションの型情報を取り出します。 operationsはorg.omg.CORBA.OperationDescriptionクラスの配列です。org.omg.CORBA.OperationDescriptionクラスの定義を以下に示します。
package org.omg.CORBA; final public class OperationDescription { /* instance variables*/ public java.lang.String name; public java.lang.String id; public java.lang.String defined_in; public java.lang.String version; public org.omg.CORBA.TypeCode result; public OperationMode mode; public java.lang.String[] contexts; public ParameterDescription[] parameters; public ExceptionDescription[] exceptions; /* constructors*/ public OperationDescription( java.lang.String _name, java.lang.String _id, java.lang.String _defined_in, java.lang.String _version, org.omg.CORBA.TypeCode _result, OperationMode _mode, java.lang.String[] _contexts, ParameterDescription[] _parameters, ExceptionDescription[] _exceptions ) { name = _name; id = _id; defined_in = _defined_in; version = _version; result = _result; mode = _mode; contexts = _contexts; parameters = _parameters; exceptions = _exceptions; } public OperationDescription() {} }parametersからパラメータ情報を取り出します。 parametersはorg.omg.CORBA.ParameterDescriptionクラスの配列です。org.omg.CORBA.ParameterDescriptionクラスの定義を以下に示します。
// 引数の種別 // PARAM_IN : inパラメータ // PARAM_OUT : outパラメータ // PARAM_INOUT : inoutパラメータ package org.omg.CORBA; final public class ParameterMode { private int _v; public static final int _PARAM_IN = 0; public static final int _PARAM_OUT = 1; public static final int _PARAM_INOUT = 2; public static final ParameterMode PARAM_IN = new ParameterMode(_PARAM_IN); public static final ParameterMode PARAM_OUT = new ParameterMode(_PARAM_OUT); public static final ParameterMode PARAM_INOUT = new ParameterMode(_PARAM_INOUT); public int value() { return _v; } private ParameterMode(int v) { _v = v; } ... } // ParameterDescription package org.omg.CORBA; final public class ParameterDescription { // instance variables public java.lang.String name; public org.omg.CORBA.TypeCode type; public IDLType type_def; public ParameterMode mode; // constructors public ParameterDescription( java.lang.String _name, org.omg.CORBA.TypeCode _type, IDLType _type_def, ParameterMode _mode ) { name = _name; type = _type; type_def = _type_def; mode = _mode; } public ParameterDescription() {} }org.omg.CORBA.OperationDescriptionクラスのメンバexceptionsがnull以外ならば、exceptionsからユーザ定義例外情報を取り出します。 exceptionsはorg.omg.CORBA.ExceptionDescriptionクラスの配列です。org.omg.CORBA.ExceptionDescriptionクラスの定義を以下に示します。
package org.omg.CORBA; final public class ExceptionDescription { /* instance variables*/ public java.lang.String name; public java.lang.String id; public java.lang.String defined_in; public java.lang.String version; public org.omg.CORBA.TypeCode type; /* constructors*/ public ExceptionDescription( java.lang.String _name, java.lang.String _id, java.lang.String _defined_in, java.lang.String _version, org.omg.CORBA.TypeCode _type ) { name = _name; id = _id; defined_in = _defined_in; version = _version; type = _type; } public ExceptionDescription() {} }これらのインタフェース情報により、DIIによる呼び出しに必要なパラメータを組み立てることができます。
基本的な呼び出し
DIIを使って呼び出す手順として、引数リストなどを先に作っておきorg.omg.CORBA.Requestオブジェクトを作成する方法と、org.omg.CORBA.Requestオブジェクトを先に作っておく方法があります。 先に引数リストを作成するにはorg.omg.CORBA.ORB.create_listかorg.omg.CORBA.ORB.create_operation_listを使います。前者はorg.omg.CORBA.NVList.addなどを使って引数を1つずつ追加していかなければいけません。後者はインタフェースリポジトリに登録されているインタフェース情報をもとに自動的に追加されます。 org.omg.CORBA.Requestオブジェクトを作成するには、org.omg.CORBA._requestまたはorg.omg.CORBA._create_requestを使います。org.omg.CORBA._create_requestは引数リストにnullを設定しておいて、後から引数を追加することもできます。 作成したorg.omg.CORBA.Requestに引数を追加するには、org.omg.CORBA.Request.argumentsで引数リストを取り出す方法と、org.omg.CORBA.Request.add_in_argなどを使う方法があります。以下の例では後者を使います。 以下ではもっとも基本的な呼び出し手順を示します。 DIIによるオペレーションの呼び出しを行うには、org.omg.CORBA.Requestオブジェクトにオペレーションの情報(引数や戻り値の型など)をセットする必要があります。 org.omg.CORBA.Requestオブジェクトを作成するには、呼び出すオブジェクトのオブジェクトリファレンスが必要です。オブジェクトリファレンスの取得方法は静的な呼び出しと同じです。不特定のオブジェクトを呼び出すクライアントを作成する場合、名前サービスのorg.omg.CosNaming.NamingContext.resolveを使うのが一般的です。 また、不特定のオブジェクトを呼び出すクライアントを作成する場合は、インタフェースの定義を取得する必要があります。WebOTX Object Broker JavaTMではインタフェース定義を取得するには、org.omg.CORBA._get_interface_defを使います。org.omg.CORBA._get_interface_def()はあらかじめインタフェースリポジトリに登録されていたインタフェースを返します。import org.omg.CosNaming.*; import org.omg.CORBA.*; public class client { public static void main(String args[]) { try { // 何らかの手段でオブジェクトリファレンスを取得 org.omg.CORBA.Object obj = ...; // インタフェースを定義しているオブジェクトの取得 InterfaceDef intfobj = org.omg.CORBA.InterfaceDefHelper.narrow(obj._get_interface()); : // インタフェース情報を取り出す org.omg.CORBA.InterfaceDefPackage.FullInterfaceDescription intfdesc = intfobj.describe_interface(); : :intfdescにはオブジェクトリファレンスが指し示すオブジェクトのすべてのインタフェース情報が入っています。この中から、目的のオペレーションを選びます。
int count = intfdesc.operations.length; OperationDescription opedesc = new OperationDescription(); for (int i = 0; i < count; i++) { // オペレーションのシーケンスから1つ取り出す opedesc = intfdesc.operations[i]; // オペレーション名が一致するものを探す(仮に"myop"を探すことにします) if (opedesc.name.equals("myop")) { break; } }名前が一致するオペレーションを取得できたら、org.omg.CORBA.Requestオブジェクトを作成します。引数には、オペレーション名を渡します。
Request req = obj._request(opedesc.name);作成したorg.omg.CORBA.Requestオブジェクトに戻り値の型を指定します。
req.set_return_type(opedesc.result);オペレーションの引数を登録します。引数にはin, out, inoutの3種類があり、それぞれ別のメソッド(add_XXX_arg)が用意されています。引数はメソッドを呼び出すたびに引数リストの後ろへ追加されます。add_XXX_argは、org.omg.CORBA.Anyを返します。返されたorg.omg.CORBA.Anyに引数を挿入します。
count = opedesc.parameters.length; ParameterDescription paradesc; Any value; for (int i = 0; i < count; i++) { // パラメータのシーケンスから1つ取り出す paradesc = opedesc.parameters[i]; // パラメータの設定 switch (paradesc.mode.value()){ case ParameterMode._PARAM_IN: switch (paradesc.type.kind().value()) { case TCKind._tk_short: short in_param = ...; req.add_named_in_arg(paradesc.name).insert_short(in_param); break; ... } break; case ParameterMode._PARAM_INOUT: switch (paradesc.type.kind().value()) { case TCKind._tk_short: short inout_param = ...; req.add_named_inout_arg(paradesc.name).insert_short(inout_param); break; ... } break; default: req.add_named_out_arg(paradesc.name); break; } }引数の組み立てが終わったら、サーバの呼び出しを行います。サーバの呼び出し方法には単方向と双方向の2種類があります。これらはIDL定義をしたときに決まります。
if (opedesc.mode == OperationMode.OP_ONEWAY) { req.send_oneway(); // 単方向呼び出しのとき } else { req.invoke(); // 双方向呼び出しのとき }双方向呼び出しで、かつ、戻り値を持っていた場合は、戻り値を取得する必要があります。戻り値は、org.omg.CORBA.Any型で取得します。
if (opedesc.result.kind() != TCKind.tk_void) { switch(opedesc.result.kind().value()) { case TCKind._tk_short: short result = req.return_value().extract_short(); break; ... } }
リクエストの発行
リクエストの発行には、4つの方法があります。DSIに必要なクラス
DSIを利用するためにはorg.omg.PortableServer.DynamicImplementationクラスを継承したクラスを作成します。このクラスがリクエストの処理を実装するDSIサーバント(DSIの実装オブジェクト)になります。DSIサーバントは、次のメソッドをオーバライドする必要があります。package org.omg.PortableServer; abstract public class Servant { ・・・ // methods for which the skeleton or application // programmer must provide an an implementation abstract public String[] _all_interfaces(POA poa, byte[] objectId); ・・・ }
package org.omg.PortableServer; abstract public class DynamicImplementation extends Servant { abstract public void invoke(org.omg.CORBA.ServerRequest request); }
interface MyInterface { long MyOperation(in long arg); };
public class MyDynamicImpl extends org.omg.PortableServer.DynamicImplementation { public MyDynamicImpl() {} private int MyOperation1(int a) { return a+1; } private int MyOperation2(int a) { return a+2; } String[] _ids = {"IDL:MyInterface:1.0"}; public String[] _all_interfaces(org.omg.PortableServer.POA poa, byte[] objectId) { return _ids; } public void invoke(org.omg.CORBA.ServerRequest request) { try { org.omg.CORBA.ORB orb = _orb(); org.omg.CORBA.Any rslt = orb.create_any(); // どのオペレーションが呼ばれたか調べる String op_name = request.operation(); if ("MyOperation".equals(op_name)) { // 引数のデコードに必要な情報をセットする org.omg.CORBA.NVList arg = orb.create_list(1); org.omg.CORBA.Any param = arg.add(org.omg.CORBA.ARG_IN.value).value(); param.type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long)); // 引数をデコードする request.arguments(arg); // IN引数を取り出す int a = param.extract_long(); // オペレーションを呼び出す org.omg.CORBA.IntHolder ret = new org.omg.CORBA.IntHolder(); // オブジェクトIDによりオペレーションを切り換える if ("myimpl1".equals(new String(_object_id()))) ret.value = MyOperation1(a); else ret.value = MyOperation2(a); // 戻り値をrequestにセットする rslt.type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long)); rslt.insert_long(ret.value); request.set_result(rslt); return; } // エラー処理または例外をrequestにセットする // org.omg.CORBA.BAD_OPERATION例外をrequestにセットする場合 org.omg.CORBA.Any exp = _orb().create_any(); org.omg.CORBA.BAD_OPERATIONHelper.insert( exp, new org.omg.CORBA.BAD_OPERATION( 0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE)); } catch (Exception e) { // エラー処理または例外をrequestにセットする e.printStackTrace(); } } public static void main(String[]args) { try { org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); org.omg.CORBA.Object o = orb.resolve_initial_references("RootPOA"); org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper.narrow(o); org.omg.CORBA.Policy policies[] = new org.omg.CORBA.Policy[1]; policies[0] = rootPOA.create_id_assignment_policy( org.omg.PortableServer.IdAssignmentPolicyValue.USER_ID); org.omg.PortableServer.POA myPOA = rootPOA.create_POA("myPOA", null, policies); // 文字列をオブジェクトIDに変換 byte[] oid1 = new String("myimpl1").getBytes(); byte[] oid2 = new String("myimpl2").getBytes(); // MyOperation1,MyOperation2を呼び出すインスタンスを作成 MyDynamicImpl impl1 = new MyDynamicImpl(); MyDynamicImpl impl2 = new MyDynamicImpl(); // サーバントを活性化 myPOA.activate_object_with_id(oid1, impl1); myPOA.activate_object_with_id(oid2, impl2); // オブジェクトリファレンスを名前サーバに登録 org.omg.CORBA.Object obj1 = myPOA.servant_to_reference(impl1); org.omg.CORBA.Object obj2 = myPOA.servant_to_reference(impl2); org.omg.CORBA.Object nsv = orb.resolve_initial_references("NameService"); org.omg.CosNaming.NamingContext ns = org.omg.CosNaming.NamingContextHelper.narrow(nsv); org.omg.CosNaming.NameComponent ncseq1[] = {new org.omg.CosNaming.NameComponent("implobj1", "")}; org.omg.CosNaming.NameComponent ncseq2[] = {new org.omg.CosNaming.NameComponent("implobj2", "")}; ns.rebind(ncseq1, obj1); ns.rebind(ncseq2, obj2); // POAマネージャの活性化 myPOA.the_POAManager().activate(); orb.run(); } catch(Exception e) { e.printStackTrace(); } } }
Caution
スレッドポリシーの設定は、POAのThreadPolicyがORB_CTRL_MODELである場合のみ有効です。ポリシーにSINGLE_THREAD_MODELが設定されている場合は、PooledThreadであっても、単一のスレッドで順次処理されます。
Caution
PooledThreadが選択されているとき、onewayオペレーション、遅延同期オペレーション、複数リクエスト発行を使用すると、必ずしもクライアントからの要求順序通りにサーバがで処理されません(順序性が保証されません)。
ネイティブコードセット | ORBがプログラム内部で取り扱う文字コードを示します。通常は変更することはできません。 |
コンバージョンコードセット | ネイティブコードセットに変換することが可能な文字コードを示します。 |
char型、string型 | wchar型、wstring型 | |
ネイティブコードセット | UCS2L1 | UCS2L1 |
コンバージョンコードセット | OSF_SJIS1 JIS_eucJP ISO8859-1 ISO646 | UTF16 |
コードセットのネゴシエーション機能
Caution
コードセットのネゴシエーション機能を使用するためには、IIOP および GIOP
のバージョンが1.1以上である必要があります(Object
Brokerは1.1もしくは1.2で動作しますので、通常は指定する必要はありません)。IIOP および GIOP
のバージョンが1.0である場合は、char 型、string 型はISO8859-1 を、wchar
型、wstring 型は UCS2L1 を使用して通信します。
コンバージョンコードセットの変更
コンバージョンコードセットは、ConversionCodeSetsプロパティ、ConversionCodeSetsWプロパティを設定することによって変更することができます。
Caution
既定値の設定で通信をおこなうことが可能ですので、通常は設定を変更する必要はありません。
コードセット名 | コードセット番号 | 説明 | エンコーディング |
---|---|---|---|
ISO8859-1 | 0x00010001 | ISO 8859-1:1987; Latin Alphabet No. 1 |
|
ISO8859-2 | 0x00010002 | ISO 8859-2:1987; Latin Alphabet No. 2 | 8859_2 |
ISO8859-3 | 0x00010003 | ISO 8859-3:1988; Latin Alphabet No. 3 | 8859_3 |
ISO8859-4 | 0x00010004 | ISO 8859-4:1988; Latin Alphabet No. 4 | 8859_4 |
ISO8859-5 | 0x00010005 | ISO/IEC 8859-5:1988; Latin-Cyrillic Alphabet | 8859_5 |
ISO8859-6 | 0x00010006 | ISO 8859-6:1987; Latin-Arabic Alphabet | 8859_6 |
ISO8859-7 | 0x00010007 | ISO 8859-7:1987; Latin-Greek Alphabet | 8859_7 |
ISO8859-8 | 0x00010008 | ISO 8859-8:1988; Latin-Hebrew Alphabet | 8859_8 |
ISO8859-9 | 0x00010009 | ISO/IEC 8859-9:1989; Latin Alphabet No. 5 | 8859_9 |
ISO646 | 0x00010020 | ISO 646:1991 IRV (International Reference Version) |
|
UCS2L1 | 0x00010100 | ISO/IEC 10646-1:1993; UCS-2, Level 1 |
|
JIS0201 | 0x00030001 | JIS X0201:1976; Japanese phonetic characters | JIS |
JIS0208:1978 | 0x00030004 | JIS X0208:1978 Japanese Kanji Graphic Characters | JIS |
JIS0208:1983 | 0x00030005 | JIS X0208:1983 Japanese Kanji Graphic Characters | JIS |
JIS0208 | 0x00030006 | JIS X0208:1990 Japanese Kanji Graphic Characters | JIS |
JIS0212 | 0x0003000a | JIS X0212:1990; Supplementary Japanese Kanji Graphic Chars | JIS |
JIS_eucJP | 0x00030010 | JIS eucJP:1993; Japanese EUC | EUCJIS |
OSF_UJIS | 0x05000010 | OSF Japanese UJIS | EUCJIS |
OSF_SJIS1 | 0x05000011 | OSF Japanese SJIS-1 | SJIS |
OSF_SJIS2 | 0x05000012 | OSF Japanese SJIS-2 | SJIS |
UTF8 | 0x05010001 | X/Open UTF-8; UCS Transformation Format 8 (UTF-8) |
|
JVC_eucJP | 0x05020001 | JVC_eucJP | EUCJIS |
JVC_SJIS | 0x05020002 | JVC_SJIS | SJIS |
Cp437 | 0x100201b5 | IBM-437 (CCSID 00437); PC USA | Cp437 |
Cp850 | 0x10020352 | IBM-850 (CCSID 00850); Multilingual IBM PC Data-MLP 222 | Cp850 |
Cp852 | 0x10020354 | IBM-852 (CCSID 00852); Multilingual Latin-2 | Cp852 |
Cp855 | 0x10020357 | IBM-855 (CCSID 00855); Cyrillic PC Data | Cp855 |
Cp857 | 0x10020359 | IBM-857 (CCSID 00857); Turkish Latin-5 PC Data | Cp857 |
Cp861 | 0x1002035d | IBM-861 (CCSID 00861); PC Data Iceland | Cp861 |
Cp862 | 0x1002035e | IBM-862 (CCSID 00862); PC Data Hebrew | Cp862 |
Cp863 | 0x1002035f | IBM-863 (CCSID 00863); PC Data Canadian French | Cp863 |
Cp864 | 0x10020360 | IBM-864 (CCSID 00864); Arabic PC Data | Cp864 |
Cp866 | 0x10020362 | IBM-866 (CCSID 00866); PC Data Cyrillic 2 | Cp866 |
Cp869 | 0x10020365 | IBM-869 (CCSID 00869); Greek PC Data | Cp869 |
Cp874 | 0x1002036a | IBM-874 (CCSID 00874); Thai PC Display Extended SBCS | Cp874 |
Cp932 | 0x100203a4 | IBM-932 (CCSID 00932); Japanese PC Data Mixed | MS932 |
Cp1250 | 0x100204e2 | IBM-1250 (CCSID 01250); MS Windows Latin-2 | Cp1250 |
Cp1251 | 0x100204e3 | IBM-1251 (CCSID 01251); MS Windows Cyrillic | Cp1251 |
Cp1252 | 0x100204e4 | IBM-1252 (CCSID 01252); MS Windows Latin-1 | Cp1252 |
Cp1253 | 0x100204e5 | IBM-1253 (CCSID 01253); MS Windows Greek | Cp1253 |
Cp1254 | 0x100204e6 | IBM-1254 (CCSID 01254); MS Windows Turkey | Cp1254 |
Cp1255 | 0x100204e7 | IBM-1255 (CCSID 01255); MS Windows Hebrew | Cp1255 |
Cp1256 | 0x100204e8 | IBM-1256 (CCSID 01256); MS Windows Arabic | Cp1256 |
Cp1257 | 0x100204e9 | IBM-1257 (CCSID 01257); MS Windows Baltic | Cp1257 |
コードセット名 | コードセット番号 | 説明 | エンコーディング |
---|---|---|---|
UCS2L1 | 0x00010100 | ISO/IEC 10646-1:1993; UCS-2, Level 1 |
|
UTF16 | 0x00010109 | ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16-bit form |
コードセットとエンコーディング
Java VMは、内部的な文字コードとしてUnicodeを用います。したがって、通信で使用されている文字コードがUnicodeではない場合、文字コードを変換する必要があります。 通信で使用されるコードセットがUCS2L1, ISO8859-1, ISO646, UTF-8, UTF-16の場合は、Object Broker Java独自の機能によってコード変換をおこないます。それ以外のコードセットが通信に使用された場合は、Javaの機能によってコード変換をおこないます。 それぞれの文字コードセットに対応するエンコーディングは上表のとおりです。また、CodeSetEncoding プロパティを設定することによって文字コードセットに対応するエンコーディング名を変更することができます。文字化けの発生について
サーバとクライアントのうち、一方がC++、もう一方がJavaである場合、通常はコードセットのネゴシエーションによって通信に使用されるコードセットにOSF_SJIS1(シフトJIS)が選択されます。 このとき、既定値では、シフトJISとUnicodeの変換のためのエンコーディングにSJISを使用しますが、下表に示す文字で文字化けが発生する場合があります。文字化けが発生する文字が以下に該当する場合は、CodeSetEncoding プロパティに「OSF_SJIS1=MS932」と設定してください。文字 | シフトJISでのコード |
---|---|
〜 | 0x8160 |
‖ | 0x8161 |
− | 0x817C |
¢ | 0x8191 |
£ | 0x8192 |
¬ | 0x81CA |
NEC 特殊文字 | 0x8740 - 0x87FC |
IBM 拡張文字 (NEC 選定) | 0xED40 - 0xEEFC |
ユーザ定義文字 (外字領域) | 0xF040 - 0xF9FC |
IBM 拡張文字 | 0xFA40 - 0xFC4B |
コードベースダウンロード機能
CORBAでは、valuetypeに関する情報をリモートの環境から取得するためのSendingContextRunTimeサービスが規定されています。 valuetypeの実装クラスおよびValueFactoryの実装クラスをローカルな環境に持っていないとき、HTTP を利用してWebサーバからダウンロードする機能をコードベースダウンロード機能と呼びます。実装クラスをダウンロードするためのURLのことをコードベースと呼びます。 通信する相手のORBからコードベースを取得し、valuetypeの実装クラスおよびValueFactoryの実装クラスをダウンロードして、valuetypeのインスタンスを作成する処理はObject Broker Javaが自動的におこないますので、アプリケーションで意識してプログラミングする必要はありません。 コードベースダウンロード機能を使用するためには、valuetypeの送信側のORBで、この機能を有効にするための設定が必要です。コードベースの設定単位
コードベースの設定は、1つのプロセスの中で複数の設定を使い分けることができます。 サーバ側は、オブジェクトID毎に設定します。コードベースの設定は、そのオブジェクトIDに対応するサーバントにのみ有効になります。オブジェクトIDはPOA.activate_object()の戻り値として取得できます。 クライアント側は、ORB毎に設定します。コードベースの設定は、そのORBに対応するリクエストにのみ有効です。ORBはORB.init()の戻り値として取得できます。 アプリケーションのプログラムでオブジェクトID(クライアントではORB)と、設定を区別するためのコードベースプロパティ名を登録する必要があります。 登録はConfig.setCodeBaseIdent()を呼び出すことによっておこないます。登録した時点でコードベースプロパティ名に対応するコードベースプロパティファイルに記述されたURLからダウンロードが可能になります。 異なるオブジェクトID(クライアントではORB)に対して同じコードベースプロパティ名を登録すれば、同じ設定を使用することができます。 プログラム内でコードベースプロパティ名の登録をしないオブジェクトID(クライアントではORB)については、プロセスで共通の設定を使用することができます。コードベースプロパティファイル
コードベースプロパティファイルは、valuetypeの実装クラスおよびValueFactoryの実装クラスをダウンロードするために、そのクラスファイルが置かれている場所を示すURLを記述するファイルです。 ただし、 コードベースプロパティファイルには ValueFactoryの実装クラスファイルのURLのみを記述します。 ValueFactoryの実装クラスでvaluetypeの実装クラスを使用していれば、そのクラスファイルも同時にダウンロードされますので、valuetypeの実装クラスファイルのURLを記述する必要はありません。* <URL> ... <URL> <Repository-ID> <URL> ... <URL> : : <Implementation-class> <URL> ... <URL> : :'*' で始まる行は、デフォルトの URL を記述します。<Repository-ID> での指定も <Implementation-class>での指定もない場合、デフォルトの URL から検索します。 いずれの指定でも URL を複数書くことができます。記述順に検索してダウンロードできた場合はそのクラスを使用します。 コードベースプロパティ名に対応するコードベースプロパティファイルのファイル名は、以下のようになります。 <コードベースプロパティ名>.cbp ファイルを格納するディレクトリはカレントディレクトリ (アプリケーションを実行したディレクトリ) になります。このディレクトリはCodeBasePropertyFileDirプロパティで変更できます。 プロセスで共通のコードベースプロパティファイルのファイル名は、以下のようになります。 カレントディレクトリ/codebase.conf このファイル名はCodeBasePropertyFileプロパティでディレクトリを含めた形で変更できます。(この指定はCodeBasePropertyFileDirプロパティより優先されます) Object Broker Javaでは、コードベースダウンロード機能を使用する場合、アプリケーションでセキュリティマネージャが設定されていなければ、RMISecurityManagerを設定して使用します(アプレットではブラウザによってセキュリティマネージャが設定されます)。 そのため、アクセス権の設定をポリシーファイルに記述する必要があります。
grant { permission java.util.PropertyPermission "*", "read, write"; permission java.io.FilePermission "${user.home}\\orb.properties", "read"; permission java.io.FilePermission "${java.home}\\lib\\orb.properties", "read"; permission java.lang.RuntimePermission "getClassLoader"; permission java.io.FilePermission "<コードベースプロパティファイル名>", "read"; permission java.net.SocketPermission "<WebサーバのIPアドレス>[:<Webサーバのポート番号>]", "connect, resolve"; permission java.net.SocketPermission "<サーバプロセスが動作するマシン名>[:<ポート番号>]", "connect, resolve"; permission java.net.SocketPermission "<サーバAPが動作するマシン名>[:<ポート番号>]", "connect, resolve"; permission java.net.SocketPermission "<クライアントAPが動作するマシン名>[:<ポート番号>]", "accept, resolve"; };
grant { permission java.io.FilePermission "<コードベースプロパティファイル名>", "read"; permission java.net.SocketPermission "<WebサーバのIPアドレス>[:<Webサーバのポート番号>]", "connect, resolve"; };
<iioploc> = "iioploc://"[<addr_list>]["/"<key_string>] <iiopname> = "iiopname://"[<addr_list>]["/"<string_name>] <addr_list> = [<address>","]* <address> <address> = [<version> <host> [":" <port>]] <version> = <major> "." <minor> "@" | "" <major> = IIOPのmajorバージョン番号 <minor> = IIOPのminorバージョン番号 <host> = ホスト名 | IPアドレス (未指定時はlocalhost) <port> = corbalocサーバのポート番号 (未指定時は2809) <key_string> = 文字列化したオブジェクトキー | "" <string_name> = 文字列化した名前シーケンスcorbaloc URL形式とcorbaname URL形式 corbaloc URL形式とcorbaname URL形式のシンタックスを説明します。
<corbaloc> = "corbaloc:"<obj_addr_list>"/"<key_string> <corbaname> = "corbaname:"<corbaloc_obj>["#"<string_name>] <corbaloc_obj> = <obj_addr_list>["/"<key_string>] <obj_addr_list> = [<obj_addr>","]* <obj_addr> <obj_addr> = <prot_addr> | <future_prot_addr> <prot_addr> = <rir_prot_addr> | <iiop_prot_addr> <iiop_prot_addr> = <iiop_id><iiop_addr> <iiop_id> = <iiop_default> | <iiop_prot_token>":" ["//"] <iiop_default> = ":" <iiop_prot_token> = "iiop" <iiop_addr> = [<version> <host> [":" <port>]] <version> = <major> "." <minor> "@" | "" <major> = IIOPのmajorバージョン番号 <minor> = IIOPのminorバージョン番号 <host> = ホスト名 | IPアドレス (未指定時はlocalhost) <port> = corbalocサーバのポート番号 (未指定時は2809) <rir_prot_addr> = <rir_prot_token>":" <rir_prot_token> = "rir" <key_string> = 文字列化したオブジェクトキー | "" <string_name> = 文字列化した名前シーケンス初期サービスのオブジェクト指定 初期サービスのオブジェクトは、ORBInitRefプロパティで指定します。 「<ObjectID>=<ObjectURL>」の形式で指定してください。
オブジェクトキー | オブジェクト |
---|---|
"NameService" | そのホスト上の名前サーバのルートコンテキスト |
"InterfaceRepository" | そのホスト上のIRサーバのRepositoryオブジェクト |
interface StateObject { attribute long state1; attribute long state2; attribute long state3; attribute long state4; };このIDLで、StateObjectから、state1, state2, state3, state4の全ての情報を得たいとすると次のようなプログラムになります。
//Java long s1 = StateObjectObj.state1(); long s2 = StateObjectObj.state2(); long s3 = StateObjectObj.state3(); long s4 = StateObjectObj.state4(); //C++ long s1 = StateObjectObj->state1(); long s2 = StateObjectObj->state2(); long s3 = StateObjectObj->state3(); long s4 = StateObjectObj->state4();この場合、4回の通信が発生します。
interface StateObject { struct State { long state1; long state2; long state3; long state4; }; State getState(); };この場合、先程のクライアントプログラムは次のように書くことができます。
//Java State state = StateObjectObj.getState(); long s1 = state.state1; long s2 = state.state2; long s3 = state.state3; long s4 = state.state4; //C++ State state = StateObjectObj->getState(); long s1 = state.state1; long s2 = state.state2; long s3 = state.state3; long s4 = state.state4;これだと、通信はgetStatus()の部分の1回しか起こりません。この例は非常に単純な例ですが、CORBAを使用した呼び出しがアプリケーション全体で最小限になるように、全体のオブジェクト構成を設計するように注意してください。
//Java public class adder { return l1+l2; } } //C++ class adder { public: long add(long l1, long l2) { return l1+l2; } }呼び出し側では
//Java long result = adderobj.add(1L, 2L); //C++ long result = addreobj->add(1L, 2L);で十分であり、エラーが起こる余地はありません。
// Java obj.add(1L,2L); // C++ obj->add(1L,2L); ※以降の図では、C++言語でのコーディング例は省略します。objはリモートプロセスで実装されるCORBAオブジェクトのオブジェクトリファレンスです。
// 足し算オブジェクトのリファレンスを取得。 obj = someobj.getAdderObj(); // 1回目の呼び出し。 4回の通信が起こる。 obj.add(...); // 同一オブジェクトリファレンスによる2回目の呼び出し。 // 2回の通信しか起こらない。 obj.add(...);しかし、これを次のように記述すると効率が非常に悪くなります。
// 足し算オブジェクトのリファレンス取得。 obj = someobj.getAdderObj(); // 1回目の呼び出し。4回の通信が起こる。 obj.add(...); // 同一の足し算オブジェクトのリファレンス再取得。 obj = someobj.getAdderObj(); // 2回目の呼び出し。4回の通信が起こる。 obj.add(...);上記のような記述では、同じオブジェクトに対する2回目の要求でも4回の通信が起きてしまいます。
IDLでの型 | Javaでの型 | Holder型 | 例外 |
---|---|---|---|
boolean | boolean | BooleanHolder | |
char | char | CharHolder | CORBA::DATA_CONVERSION |
wchar | char | CharHolder | CORBA::DATA_CONVERSION |
octet | byte | ByteHolder | |
string | java.lang.String | StringHolder | CORBA::BAD_PARAM CORBA::DATA_CONVERSION |
wstring | java.lang.String | StringHolder | CORBA::BAD_PARAM CORBA::DATA_CONVERSION |
short | short | ShortHolder | |
unsigned short | short | ShortHolder | |
long | int | IntHolder | |
unsigned long | int | IntHolder | |
long long | long | LongHolder | |
unsigned long long | long | LongHolder | |
float | float | FloatHolder | |
double | double | DoubleHolder | |
fixed | java.math.BigDecimal | FixedHolder | CORBA::DATA_CONVERSION |
// IDL module Example { interface Face { const long aLongerOne = -321; }; const long aLongOne = -123; };
// Generated Java package Example; public interface FaceOperations { } public interface Face extends FaceOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity { int aLongerOne = (int) (-321L); } public interface aLongOne { int value = (int) (-123L); }
// IDL enum EnumType {a, b, c};
// Generated Java public class EnumType implements org.omg.CORBA.portable.IDLEntity { public static final int _a = 0; public static final EnumType a = new EnumType(_a); public static final int _b = 1; public static final EnumType b = new EnumType(_b); public static final int _c = 2; public static final EnumType c = new EnumType(_c); public int value() {...} public static EnumType from_int(int value) {...} // コンストラクタ protected EnumType(int) {...} };
IDLの例外 | Javaクラス名 |
---|---|
CORBA::UNKNOWN | org.omg.CORBA.UNKNOWN |
CORBA::BAD_PARAM | org.omg.CORBA.BAD_PARAM |
CORBA::NO_MEMORY | org.omg.CORBA.NO_MEMORY |
CORBA::IMP_LIMIT | org.omg.CORBA.IMP_LIMIT |
CORBA::COMM_FAILURE | org.omg.CORBA.COMM_FAILURE |
CORBA::INV_OBJREF | org.omg.CORBA.INV_OBJREF |
CORBA::NO_PERMISSION | org.omg.CORBA.NO_PERMISSION |
CORBA::INTERNAL | org.omg.CORBA.INTERNAL |
CORBA::MARSHAL | org.omg.CORBA.MARSHAL |
CORBA::INITIALIZE | org.omg.CORBA.INITIALIZE |
CORBA::NO_IMPLEMENT | org.omg.CORBA.NO_IMPLEMENT |
CORBA::BAD_TYPECODE | org.omg.CORBA.BAD_TYPECODE |
CORBA::BAD_OPERATION | org.omg.CORBA.BAD_OPERATION |
CORBA::NO_RESOURCES | org.omg.CORBA.NO_RESOURCES |
CORBA::NO_RESPONSE | org.omg.CORBA.NO_RESPONSE |
CORBA::PERSIST_STORE | org.omg.CORBA.PERSIST_STORE |
CORBA::BAD_INV_ORDER | org.omg.CORBA.BAD_INV_ORDER |
CORBA::TRANSIENT | org.omg.CORBA.TRANSIENT |
CORBA::FREE_MEM | org.omg.CORBA.FREE_MEM |
CORBA::INV_IDENT | org.omg.CORBA.INV_IDENT |
CORBA::INV_FLAG | org.omg.CORBA.INV_FLAG |
CORBA::INTF_REPOS | org.omg.CORBA.INTF_REPOS |
CORBA::BAD_CONTEXT | org.omg.CORBA.BAD_CONTEXT |
CORBA::OBJ_ADAPTER | org.omg.CORBA.OBJ_ADAPTER |
CORBA::DATA_CONVERSION | org.omg.CORBA.DATA_CONVERSION |
CORBA::OBJECT_NOT_EXIST | org.omg.CORBA.OBJECT_NOT_EXIST |
CORBA::TRANSACTION_REQUIRED | org.omg.CORBA.TRANSACTION_REQUIRED |
CORBA::TRANSACTION_ROLLEDBACK | org.omg.CORBA.TRANSACTION_ROLLEDBACK |
CORBA::INVALID_TRANSACTION | org.omg.CORBA.INVALID_TRANSACTION |
CORBA::INV_POLICY | org.omg.CORBA.INV_POLICY |
CORBA::CODESET_INCOMPATIBLE | org.omg.CORBA.CODESET_INCOMPATIBLE |