9.3.3 OTMクライアントで例外を参照する方法
OTMクライアントは,EJBからスローされる例外クラスをそのままキャッチできないので,TSCユーザプロキシ(スタブ)で変換してからキャッチしています。
以降ではTSCユーザプロキシで変換した例外について説明します。
(1) OTMクライアントで受け取る例外一覧
EJBで発生した例外と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を参照) |
(2) 例外構造体について
(a) 例外構造体の概要
OTMクライアントでは再帰的な構造のデータを解釈できない,valuetypeが使用できないという制限があるため,EJBからの例外は次の図のように構造体をメンバに持つ例外に変換されます。この構造体を例外構造体と呼びます。
例外は例外構造体に変換されますが,OTMクライアントでは,例外構造体をメンバとして持った例外をキャッチします。ユーザがMsgServerExceptionをEJBからスローすると,OTMクライアントはMsgServerEx例外としてキャッチします。MsgServerEx例外のメンバであるvalueは,例外構造体 MsgServerExceptionになります。
(b) 例外構造体のメンバ
例外構造体に含まれるメンバ名と内容を次の表に示します。
項番 |
構造体のメンバ |
内容 |
---|---|---|
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構造体の各メンバに設定される情報を,次の表に示します。
項番 |
フィールド名 |
内容 |
例 |
---|---|---|---|
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); }