Hitachi

Cosminexus V11 アプリケーションサーバ 機能解説 拡張編


9.3.3 OTMクライアントで例外を参照する方法

OTMクライアントは,EJBからスローされる例外クラスをそのままキャッチできないので,TSCユーザプロキシ(スタブ)で変換してからキャッチしています。

以降ではTSCユーザプロキシで変換した例外について説明します。

〈この項の構成〉

(1) OTMクライアントで受け取る例外一覧

EJBで発生した例外とOTMクライアントで受け取る例外の対応一覧を,次の表に示します。

表9‒5 OTMクライアントで受け取る例外一覧

項番

EJBで発生した例外

OTMクライアントで受け取る例外

1

Javaユーザ定義例外

(java.lang.Exceptionを継承)

ユーザ定義例外(IDL定義のexceptionを参照)

2

Javaユーザ定義例外

(java.rmi.RemoteExceptionを継承)

TSC::java::rmi::RemoteEx例外

3

Javaシステム定義例外

(java.lang.Exceptionを継承した例外)

TSCUnknown例外(該当Javaシステム定義例外)

4

Javaランタイム例外

(java.lang.RuntimeExceptionを継承した例外)

TSC::java::rmi::RemoteEx例外

5

Javaシステム定義エラー

(java.lang.Errorを継承したエラー)

TSC::java::rmi::RemoteEx例外

6

java.rmi.RemoteException

TSC::java::rmi::RemoteEx例外

7

CORBAシステム例外

(org.omg.CORBA.SystemExceptionを継承した例外)

TSCUnknown例外(該当TSCシステム例外)

8

CORBAユーザ例外

(org.omg.CORBA.UserExceptionを継承した例外)

ユーザ定義例外(IDL定義のexceptionを参照)

注※

例外名称が〜Exceptionの場合〜Exになります。そのほかの場合,末尾にExが付加されます。例外のメンバvalueの値が例外構造体。

(2) 例外構造体について

(a) 例外構造体の概要

OTMクライアントでは再帰的な構造のデータを解釈できない,valuetypeが使用できないという制限があるため,EJBからの例外は次の図のように構造体をメンバに持つ例外に変換されます。この構造体を例外構造体と呼びます。

図9‒2 例外クラスと例外構造体

[図データ]

例外は例外構造体に変換されますが,OTMクライアントでは,例外構造体をメンバとして持った例外をキャッチします。ユーザがMsgServerExceptionをEJBからスローすると,OTMクライアントはMsgServerEx例外としてキャッチします。MsgServerEx例外のメンバであるvalueは,例外構造体 MsgServerExceptionになります。

図9‒3 例外クラスからの例外構造体の取得

[図データ]

(b) 例外構造体のメンバ

例外構造体に含まれるメンバ名と内容を次の表に示します。

表9‒6 例外構造体のメンバの説明

項番

構造体のメンバ

内容

1

order

OTMアプリケーションの開発者は意識する必要はありません。

OTMクライアントが例外として受け取るために必要な情報です。

2

count

3

cause

OTMアプリケーションの開発者は意識する必要はありません。

OTMクライアントの場合は,EJBからcauseに値を設定して例外をスローしないでください。

4

detailMessage

スーパクラスに指定した詳細メッセージです。

5

stackTrace

EJB側の例外が生成されるまでのスタックトレースです。

6

メンバ変数

Javaユーザ定義例外で設定したメンバ変数です。

RemoteExceptionの場合は,メンバ変数はありません。

(c) スタックトレースの各情報

例外構造体のメンバであるstackTraceは,StackTraceElement構造体の配列であり,StackTraceElement構造体には,スタックトレースの1スタック分の情報が入っています。

StackTraceElement構造体の各メンバに設定される情報を,次の表に示します。

表9‒7 StackTraceElement構造体のメンバ

項番

フィールド名

内容

1

LineNumber

ソースの行番号

29

2

declaringClass

クラス名

jp.co.Hitachi.soft.test.ejb.testMsgSyncServiceDelEJB

3

FileName

ファイル名

testMsgSyncServiceDelEJB.java

4

MethodName

メソッド名

InvokeBinary

(3) OTMクライアントで例外情報を参照する例

OTMクライアントで,EJBからの例外を参照する方法について,サンプルコードを用いて説明します。

Javaユーザ定義例外を次に示します。

Package jp.co.Hitachi.soft.test;
public class MsgServerException extends Exception
{
    public MsgServerException()
    {
      m_case=1;
    }
    private int m_case;
}

(a) C++で例外情報を参照する例

C++で例外情報を参照する例を次に示します。

#define ERR_FORMAT "EC=%d,DC=%d,PC=%d,CS=%d,MC1=%d,MC2=%d,MC3=%d,MC4=%d\n"
// 指定された文字列の長さを返す関数
int my_wstringlen(CORBA::WChar* arg){
    int i;
    for(i=0;arg[i] != 0;i++);
    return i;
}
// 指定された文字列を表示する関数
void my_print_wstring(CORBA::WChar* arg){
    for(int i=0;i < my_wstringlen(arg); i++){
      printf("%c", arg[i]);
    }
}
 
int main(int argc, char** argv){
  try {
      // EJB呼び出し処理省略
  }catch(jp::co::Hitachi::soft::test::MsgServerEx &e){
   // EJBがJavaユーザ定義例外 MsgServerExceptionをスロー
    jp::co::Hitachi::soft::test::CSCMsgServerException& ex_val = e.value;
 
    // 詳細メッセージの出力
    printf("detailMessage:");
    ::TSC::TSCWStringValue& detailMessage = ex_val.detailMessage;
    CORBA::WChar* w_detail_msg = new CORBA::WChar[detailMessage.value.length()];
    w_detail_msg = TSCgetWString(detailMessage.value );
    my_print_wstring(w_detail_msg);
    printf("\n");
 
    // メンバ変数 m_case の出力
    printf("m_case:%d", ex_val.m_case);
    // スタックトレースの出力
    ::TSC::java::lang::seq1_StackTraceElement& stackTrace = ex_val.stackTrace;
    CORBA::ULong len = stackTrace.value.length();
    :TSC::java::lang::StackTraceElement stackTraceElement;
    for ( int i = 0 ; i < len ; i ++ ) {
        stackTraceElement = stackTrace.value [ i ] ;
        ::TSC::TSCWStringValue& className = stackTraceElement.declaringClass;
        ::TSC::TSCWStringValue& methodName= stackTraceElement.methodName;
        ::TSC::TSCWStringValue& fileName = stackTraceElement.fileName;
        CORBA::Long lineNumber= stackTraceElement.lineNumber;
 
        CORBA::WChar* w_class_name = new CORBA::WChar[className.value.length()];
        w_class_name = TSCgetWString( className.value );
 
      CORBA::WChar* w_method_name = new CORBA::WChar[methodName.value.length()];
      w_method_name = TSCgetWString( methodName.value );
 
      CORBA::WChar* w_file_name = new CORBA::WChar[fileName.value.length()];
      w_file_name = TSCgetWString( fileName.value );
 
      printf("at ");
      my_print_wstring(w_class_name);
      printf(".");
      my_print_wstring(w_method_name);
      printf("(");
      my_print_wstring(w_file_name);
      printf(":%d)\n",lineNumber);
    }
}catch(TSC::java::rmi::RemoteEx &e){
    // EJBからJavaランタイム例外がスロー
    // EJBからJavaシステム定義エラーがスロー
    // EJBからjava.rmi.RemoteExceptionがスロー
 
    TSC::java::rmi::RemoteException& ex_val = e.value;
 
    // 詳細メッセージの出力
    printf("detailMessage:");
    ::TSC::TSCWStringValue& detailMessage = ex_val.detailMessage;
    CORBA::WChar* w_detail_msg = new CORBA::WChar[detailMessage.value.length()];
    w_detail_msg = TSCgetWString(detailMessage.value );
    my_print_wstring(w_detail_msg);
    printf("\n");
 
    // スタックトレースの出力
    ::TSC::java::lang::seq1_StackTraceElement& stackTrace = ex_val.stackTrace;
    CORBA::ULong len = stackTrace.value.length();
    :TSC::java::lang::StackTraceElement stackTraceElement;
    for ( int i = 0 ; i < len ; i ++ ) {
        stackTraceElement = stackTrace.value [ i ] ;
        ::TSC::TSCWStringValue& className = stackTraceElement.declaringClass;
        ::TSC::TSCWStringValue& methodName= stackTraceElement.methodName;
        ::TSC::TSCWStringValue& fileName = stackTraceElement.fileName;
        CORBA::Long lineNumber= stackTraceElement.lineNumber;
 
        CORBA::WChar* w_class_name = new CORBA::WChar[className.value.length()];
        w_class_name = TSCgetWString( className.value );
      CORBA::WChar* w_method_name = new CORBA::WChar[methodName.value.length()];
      w_method_name = TSCgetWString( methodName.value );
 
      CORBA::WChar* w_file_name = new CORBA::WChar[fileName.value.length()];
      w_file_name = TSCgetWString( fileName.value );
 
      printf("at ");
      my_print_wstring(w_class_name);
      printf(".");
      my_print_wstring(w_method_name);
      printf("(");
      my_print_wstring(w_file_name);
      printf(":%d)\n",lineNumber);
    }
} catch(TSCSystemException& se) {
    // EJBからJavaシステム定義例外がスロー
    // EJBからCORBAシステム例外がスロー
    // EJBの呼び出しに失敗
    printf(ERR_FORMAT,
            se.getErrorCode(), se.getDetailCode(),
            se.getPlaceCode(), se.getCompletionStatus(),
            se.getMaintenanceCode1(), se.getMaintenanceCode2(),
            se.getMaintenanceCode3(), se.getMaintenanceCode4());
} catch(UserExcept& se) {
    // EJBからCORBAユーザ例外がスロー
    printf("UserExcept\n");
}

(b) Javaで例外情報を参照する例

Javaで例外情報を参照する例を次に示します。

// byte[]をchar[]に変換し,Stringにする関数
private static String myString(byte[] barray) {
    char[] carry = new char[barray.length/2];
    for ( int i=0;i<carry.length;i++) {
        carry[i] = (char)((( barray[i*2]& 0xff) << 8 ) | barray[(i*2)+1]& 0xff) ;
    }
    return new String(carry);
}
 
public static void main(String[] args) {
  try {
      // EJB呼び出し処理省略
  }catch(jp.co.Hitachi.soft.test.MsgServerEx ex) {
 
     // EJBがJavaユーザ定義例外 MsgServerExceptionをスロー
    jp.co.Hitachi.soft.csc.msg.message.reception.MsgServerException testException = ex.value;
 
    // 詳細メッセージの出力
    System.out.println ("detailMessage:"+ myString(testException.detailMessage);
 
    // メンバ変数 m_case の出力
    System.out.println ("m_case:%d"+ testException .m_case);
 
    // スタックトレースの出力
    TSC.java.lang.StackTraceElement[] stackElements= testException.stackTrace.value;
    java.lang.StringBuffer stb = new java.lang.StringBuffer();
 
    for (int i=0;i<stackElements.length;i++) {
        stb = stb.append("at ");
        stb = stb.append(myString(stackElements[i].declaringClass.value));
        stb = stb.append(".");
        stb = stb.append(myString(stackElements[i].methodName.value));
        stb = stb.append("(");
        stb = stb.append(myString(stackElements[i].fileName.value));
        stb = stb.append(":");
        stb = stb.append(stackElements[i].lineNumber);
        stb = stb.append(")");
        stb = stb.append("\n");
    }
        System.out.println(stb.toString());
}catch(TSC.java.rmi.RemoteEx ex) {
    // EJBからJavaランタイム例外がスロー
    // EJBからJavaシステム定義エラーがスロー
    // EJBからjava.rmi.RemoteExceptionがスロー
    TSC.java.rmi.RemoteException testException = ex.value;
 
    // 詳細メッセージの出力
    System.out.println ("detailMessage:"+ myString(testException.detailMessage);
    // スタックトレースの出力
    TSC.java.lang.StackTraceElement[] stackElements= testException.stackTrace.value;
    java.lang.StringBuffer stb = new java.lang.StringBuffer();
 
    for (int i=0;i<stackElements.length;i++) {
        stb = stb.append("at ");
        stb = stb.append(myString(stackElements[i].declaringClass.value));
        stb = stb.append(".");
        stb = stb.append(myString(stackElements[i].methodName.value));
        stb = stb.append("(");
        stb = stb.append(myString(stackElements[i].fileName.value));
        stb = stb.append(":");
        stb = stb.append(stackElements[i].lineNumber);
        stb = stb.append(")");
        stb = stb.append("\n");
    }
        System.out.println(stb.toString());
} catch(TSCSystemException tsc_se) {
    // EJBからJavaシステム定義例外がスロー
    // EJBからCORBAシステム例外がスロー
    // EJBの呼び出しに失敗
    System.out.println(tsc_se);
} catch(UserExcept tsc_se) {
    // EJBからCORBAユーザ例外がスロー
    System.out.println("catch" + tsc_se.value);
}