9. EJBゲートウェイ

9.1. EJBゲートウェイの概要

WebOTXはVisual Basicで開発したクライアントアプリケーションから、EJBサーバアプリケーションの通信を実現するEJBゲートウェイを提供しています。本節では、EJBゲートウェイを利用したアプリケーションの開発方法について説明します。

EJBゲートウェイはVisual Basic 6.0, Visual Basic .NET, Visual Basic 2005〜2012をサポートしています。

Memo 以下の説明では、Visual Basic 6.0は「VB6.0」、Visual Basic .NET以降(Visual Basic 2005〜2012を含む)は「VB.NET」と省略しています。

EJBゲートウェイと関連コンポーネントの概要図を次に示します。


EJBゲートウェイの概要図

図の水色で示す値は、通信に使用するポート番号です。コンポーネント間の通信で使用するプロトコルとポート番号は次のとおりです。

クライアント サーバ プロトコル ポート番号(初期ドメインの既定値)
Webブラウザ Webサーバ HTTP HTTPは 80
SSL使用時のHTTPSは 443
ダウンローダ Webサーバ
Object Broker C++ 名前サーバ IIOP 2809
Object Broker C++ IIOPリスナ RMI/IIOP EXP
ExpressとDeveloperのテストサーバは7780
STDENT
Standard, Enterpriseは5151

Memo RMI/IIOP (RMI over IIOP) はCORBAの標準プロトコルであるIIOP (Internet Inter-ORB Protocol) を使用して、RMI (Remote Method Invocation) のインタフェースを実行する機能で、RMIとCORBAの相互運用を実現します。

9.2. EJBゲートウェイの提供機能

EJBゲートウェイの提供機能は次のとおりです。

以下に使用可能なデータ型について説明します。

9.2.1. 使用可能なデータ型

EJBゲートウェイで使用可能なデータ型のマッピングは次のとおりです。

Java型 VB6.0型 VB.NET型 .NET System型 引数, 戻り値 配列注1
void 省略 省略 System.Void
byte Byte SByte注2 System.SByte
short Integer Short System.Int16
char UShort注2 System.UInt16
int Long Integer System.Int32
long Long System.Int64
float Single Single System.Single
double Double Double System.Double
boolean Boolean Boolean System.Boolean
java.lang.String String String System.String
ユーザ定義JavaBean注3 Object Object System.Object
java.util.Date Date Date System.DateTime ×
java.util.Vector注4 Variant
Variant()
Object
Object()
System.Object
System.Object()
×
Caution
注1
配列を使用する場合、添え字の下限は 0になります。
可変長配列を使用する場合は、Dim Var() As xxxxx で宣言します。
ジャグ配列(各次元の要素数が異なる多次元配列)は使用できません。
詳細は[配列の使用方法]を参照してください。
注2
VB 2005からサポートされた型です。VB.NET 2003以前の環境で使用する場合は .NET FrameworkのSystem型を使用してください。
注3
ユーザ定義JavaBeanを生成するには、J2EE.BridgeオブジェクトAPIのJavaNewメソッドを使用します。詳細は[ユーザ定義JavaBeanの使用方法]を参照してください。
ユーザ定義JavaBeanの要素として java.util.Datejava.util.Vectorは使用できません。
注4
java.util.Vectorの要素として使用できる型は、javaのプリミティブラップクラス (java.langパッケージのByte, Short, Integer, Long, Float, Double, Character, Boolean) とjava.lang.Stringです。

9.3. 環境構築と環境設定

開発環境と実行環境の環境構築 および、動作環境の設定について説明します。

開発環境の構築

開発環境にEJBゲートウェイをインストールする方法は次のとおりです。

実行環境の構築

実行環境(開発環境で作成したアプリケーションを実行する環境)にEJBゲートウェイをインストールするには次の2通りの方法があります。

動作環境の設定

EJBゲートウェイの動作を変更する方法について説明します。

次のような設定単位と優先順位があり、設定するにはクライアントのレジストリを編集します。

ユーザ単位で設定 >> マシン単位で設定

編集するレジストリキーによって、有効範囲をユーザ単位とマシン単位に設定できます。

有効範囲 レジストリキー
ユーザ単位 HKEY_CURRENT_USER\Software\NEC\WebOTX\EJBGW
マシン単位 HKEY_LOCAL_MACHINE\Software\NEC\WebOTX\EJBGW

対象のクライアントで上記のレジストリキーを作成し、この配下に値を設定することにより、動作を変更することができます。レジストリに設定する内容は次のとおりです。

名 前 種 類 値(既定値)
TraceFilename 文字列
(REG_SZ)
取得するトレースファイル名(既定値: ejbgw.log
255文字以内の文字列を設定します。
出力先の既定値は作業フォルダ(カレントディレクトリ)です。出力先を変更するには、ファイル名をフルパスで指定してください。
TraceLevel DWORD
(REG_DWORD)
トレースのレベル(既定値: 5)
1
即時に訂正すべき状態
2
致命的なエラー
3
一般的なエラー
4
警告メッセージ
5
通知メッセージ
6
情報メッセージ(運行履歴用)
7
デバッグメッセージ(障害解析時)
障害時には7を設定した状態のトレースを採取してください。
TraceSize DWORD
(REG_DWORD)
トレースサイズの上限(既定値: 64Kバイト)
トレースサイズの上限をKバイト単位で設定します。この上限を超えると、ファイル名の末尾に「.bak」を付加してバックアップし、新しいトレースファイルを作成します。
TraceMulti DWORD
(REG_DWORD)
プロセス別にトレースファイルを分割する
0
トレースファイルを分割しない(既定値)
1
トレースファイル名にプロセス番号を付加して、プロセス毎にトレースファイルを作成する
MaxObject DWORD
(REG_DWORD)
オブジェクト数の上限(既定値: 2048個)
システムに過剰な負荷を与えるのを防止するため、オブジェクト数には上限値が設定されています。 既定値から拡張する場合、2049〜65535の範囲で設定します。 上限を超えると、エラー A1028108が発生します。
NullElementReplaceEmptyString DWORD
(REG_DWORD)
文字列配列内の Nothingの扱い
文字列配列内の Nothingを nullとして送信するか、V6以前の仕様と互換を持たせるために、 空文字列("")として送信するかを設定します。
0
nullとして送信する(既定値)
1
空文字列("")として送信する(V6互換)
ネットワーク環境の設定

EJBゲートウェイの通信に必要なネットワーク設定について説明します。

ポート番号/プロトコル ファイル名 機能名
80/TCP
(既定値)
Webサーバのファイル名を指定します。 IISの場合、登録済みの名前から「Web サーバー」または、「World Wide Web サービス」を選択します。 IIS以外の場合はWebサーバのマニュアルを参照して、該当するファイル名を確認してください。 Webサーバ
2809/TCP
(既定値)
<インストールディレクトリ>\ObjectBroker\bin\namesv.exe 名前サーバ
7780/TCP
(既定値)
EXP
JavaVM上 (javaw.exe) で動作するため、固有のファイル名がありません。ポート番号を設定してください。
IIOPリスナ
5151/TCP
(既定値)
STDENT
<インストールディレクトリ>\Trnsv\bin\iioplsn.exe
IIOPリスナ
最大待ち時間(タイムアウト)を変更する場合

クライアントからサーバに発行したメソッド等のリクエストは既定で30秒の最大待ち時間(タイムアウト)があり、この時間に応答がない場合は、エラー A1028117が発生します。

最大待ち時間を既定値の30秒から変更する場合、クライアントのレジストリに Object BrokerのRequestTimeoutを適用してください(値がない場合は作成してください)。

レジストリキー HKEY_LOCAL_MACHINE\SOFTWARE\NEC\ObjectSpinner\1
名 前 種 類 値(既定値)
RequestTimeout 文字列
(REG_SZ)
メソッド呼び出しのタイムアウト(既定値: 30秒)
タイムアウト時間を秒単位で設定します。
処理が戻るまで待つ場合は0を設定します。
高負荷時を考慮して10秒以下は設定しないでください。
受信データが8Mバイトを超える場合

受信データが8M(8,388,608)バイトを超える場合、クライアントのレジストリに Object BrokerのMaxMessageSizeを適用してください(値がない場合は作成してください)。

ただし、サーバ側の送受信上限値 99,999,998(約100M)バイトを超えるデータを受信することはできません。詳細については、 [高度な管理と運用サイクルガイド > 2. チューニング > 2.1.4.9. 電文長の長いメッセージの送受信] を参照してください。

レジストリキー HKEY_LOCAL_MACHINE\SOFTWARE\NEC\ObjectSpinner\1
名 前 種 類 値(既定値)
MaxMessageSize 文字列
(REG_SZ)
受信データの上限(既定値: 8388608バイト)
既定値から拡張する場合、バイト単位で 8388609〜99999998の範囲を指定します。

9.4. 制御ファイルの登録

EJBゲートウェイを用いたVisual Basicアプリケーションの開発には、事前準備として次のような手順が必要になります。

  1. EJBアプリケーションの作成
  2. rmicによるIDLファイルの生成
  3. i2jによるIFファイルの生成
  4. 制御ファイル(GC1, TLB)の生成と登録

以下に各手順について説明します。

  1. EJBアプリケーションの作成
    WebOTX Developer's Studio などによりEJBを作成します。
    メソッドの引数や戻り値で使用できる型とJavaからVisual Basicへのマッピングについては、[使用可能なデータ型]を参照してください。

    Javaソース内のパッケージやクラスなどの名称にIDLの予約語を使用すると、以下の手順でIFファイルが生成できない場合があります。このため、以下に示すIDLの予約語は使用しないようにしてください。

    IDL予約語一覧
    abstract exception inout provides truncatable
    any emits interface public typedef
    attribute enum local publishes typeid
    boolean eventtype long raises typeprefix
    case factory module readonly unsigned
    char FALSE multiple setraises union
    component finder native sequence uses
    const fixed Object short ValueBase
    consumes float octet string valuetype
    context getraises oneway struct void
    custom home out supports wchar
    default import primarykey switch wstring
    double in private TRUE

    EJBアプリケーションの開発方法については、[3. EJBアプリケーションの開発]を参照してください。 作成したEJBアプリケーションを配備する方法については、 [ドメイン構築・基本設定ガイド > 5. アプリケーション > 5.4. 配備、再配備と置換] を参照してください。

  2. rmicによるIDLファイルの生成
    JDK同梱のrmicコマンドを使用して、1.で作成したEJBホームのclassファイルからIDLファイルを生成します。
    rmicコマンドは <JDKインストールディレクトリ>\binフォルダ内にあります。
    EJBのclassファイルはjavaee.jarを参照しているため、-classpathオプションにより javaee.jarのクラスパスを指定します。
    [例] EJBホームが SampleHome.classの場合
    set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_xx
    set J2EE_HOME=C:\WebOTX
    
    set ADDCLASSPATH=-classpath ".;%J2EE_HOME%\lib\javaee.jar;%CLASSPATH%"
    
    "%JAVA_HOME%\bin\rmic" %ADDCLASSPATH% -idl -d rmic_idl SampleHome
    
     SampleHome.idlが生成されます。
    
  3. i2jによるIFファイルの生成
    Object Broker Javaのi2jを使用して、2.で作成した IDLファイルから IFファイルを生成します。
    i2jコマンドは <WebOTX Developer (for CORBA Application)インストールディレクトリ>\ObjectBroker\binフォルダ内にあります。

    Java 7環境で使用するには、-Iオプションにより、Java 7対応のIDLファイルを優先してインクルードする必要があります(-Iオプション指定が複数になる場合は、先頭で指定します)。
    Java 7対応のIDLファイルは <WebOTX Developer (for CORBA Application)インストールディレクトリ>\COMBridge\forJava7フォルダ内にあります。 あるいは、 [サンプル集 > EJBゲートウェイ] に収録されている ejbgw.zip の中に、ejbgw\Server_EJB\forJava7 または、ejbgw\Server_EJB30\forJava7フォルダとして格納されています。
    [例] EJBホームに対応したIDLファイル名が SampleHome.idlの場合
    i2j -i -I<forJava7のパス> -Irmic_idl -rmicidl -di2j_java rmic_idl\SampleHome.idl
    
     SampleHome.ifが生成されます。
    
  4. 制御ファイル (GC1, TLB) の生成と登録
    制御ファイルの生成と登録には次の2通りの方法があります。
    • ダウンローダ管理ツールで生成+ダウンローダで登録
      これは本番運用向けの方法です(間接的にIFファイルを使用します)。
      ダウンローダ管理ツールを使用してクライアント配布環境を作成し、制御ファイルを生成します。
      次に、ダウンローダを使用してクライアント配布環境からクライアントアプリケーションをダウンロードします。ダウンロード時に制御ファイルが登録されます。
    • IFコンパイラで生成および登録
      これは開発評価向けの方法です(直接IFファイルを使用します)。
      WebOTX Developer (for CORBA Application)が提供するIFコンパイラ(woifgenコマンド)を使用します。IFコンパイラは制御ファイルの生成と登録を行います。

    登録により制御ファイル (GC1, TLB) のパス情報がレジストリに記録されます。このため、制御ファイル (GC1, TLB) は削除しないでください。移動した場合は、移動後に再登録してください。

以降は開発評価向けの方法について説明します。本番運用向けのクライアント配布環境を作成する方法については、 [ Download Contents > 運用ガイド]を参照してください。

IFコンパイラ(woifgenコマンド)は次のように使用します。コマンドの詳細については、[コマンドリファレンス]を参照してください。

[例] EJBホームに対応したIFファイル名が SampleHome.ifの場合
woifgen SampleHome.if

 SampleHome.gc1とSampleHome.tlbが生成・登録されます。

Caution
Windows Vista以降でUAC(ユーザアカウント制御)が有効の場合、IFコンパイラがUACの影響を受けることがあります。詳しくは、[コマンドリファレンス]の注意事項を参照してください。

9.5. クライアントAPIの使用方法

EJBゲートウェイのAPIを利用するには J2EE.Bridgeオブジェクトを使用する必要があります。以下に使用する環境毎にJ2EE.Bridgeオブジェクトの参照を追加する方法を説明します。

  1. Visual Basic 6.0からJ2EE.Bridgeオブジェクトを使用する
    参照設定を追加するには、VB6.0の[プロジェクト]/[参照設定]メニューから[参照設定]ダイアログを開き、[参照可能なライブラリファイル]から "J2EE Bridge Object Library" を選択し、[OK]ボタンを押します。


    VB6.0の[参照設定]ダイアログ

  2. Visual Basic .NETからJ2EE.Bridgeオブジェクトを使用する
    参照設定を追加するには、VB.NETの[プロジェクト]/[参照の追加]メニューから[参照の追加]ダイアログを開き、[COM]タブ内から "J2EE Bridge Object Library" を選択し、[選択]ボタンに続けて、[OK]ボタンを押します。


    VB 2008の[参照の追加]ダイアログ

Memo クライアントAPIの詳細(リファレンス)については、 [リファレンス集 開発編(共通) > 4. CORBA > 4.7. CORBA, EJBゲートウェイ] を参照してください。

9.6. プログラミング・開発ガイド

EJBゲートウェイを用いたVisual Basicアプリケーションの開発について説明します。
処理毎に以下の項目に分けて説明します。

サンプルソースは、マニュアルのサンプルをインストールしたディレクトリ配下のsamples\JavaEE\ejbgw.zipに格納されています。

以下に各項目について説明します。

9.6.1. 基本的な使用方法

EJBゲートウェイの基本的な使用方法として、J2EE.Bridgeオブジェクトの作成から解放までに必要な処理は次のようになります。

  1. J2EE.Bridgeオブジェクトの作成
  2. 名前サーバのURL設定
  3. homeオブジェクトの取得
  4. remoteオブジェクトの生成
  5. remoteオブジェクトメソッドの呼び出し
  6. エラー処理
  7. 各オブジェクトの解放

以下に各処理手続きについて説明します。

なお、J2EE.BridgeオブジェクトAPIの詳細については、 [リファレンス集 開発編(共通) > 4. CORBA > 4.7. CORBA, EJBゲートウェイ] を参照してください。

  1. J2EE.Bridgeオブジェクトの作成
    J2EE.Bridgeオブジェクトを生成するには、次のように Newメソッドを使用します。
    [VB6.0, VB.NET]
    '(VB.NETの場合、Setステートメントは不要)
    Dim J2eebr As J2EE.Bridge
    
    'J2EE.Bridgeオブジェクトの生成
    Set J2eebr = New J2EE.Bridge
    
  2. 名前サーバのURL設定
    名前サーバのURLを設定するには、次のようにJ2EE.BridgeオブジェクトのsetProviderURLを使用します。
    パラメータのURLは "corbaname://サーバ名:ポート番号"の形式で指定します。ポート番号を省略した場合は既定値ポート番号(2809)が使用されます。
    setProviderURLを使用しない場合は、localhostの既定値ポート番号(2809)が使用されます。
    [VB6.0, VB.NET]
    '名前サーバのURL設定(ポート番号の省略時は既定値の2809)
    Call J2eebr.setProviderURL("corbaname://localhost")
    

    Caution
    IPv6形式のIPアドレスを直接指定する場合は、アドレスの両端を角括弧([ ])で囲むようにしてください。

  3. homeオブジェクトの取得
    homeオブジェクトを取得するには、次のようにJ2EE.Bridgeオブジェクトのlookupを使用します。
    第1パラメータはJNDI名、第2パラメータはhomeオブジェクト名です。
    [VB6.0, VB.NET]
    '(VB.NETの場合、Setステートメントは不要)
    Dim home As Object
    
    'homeオブジェクトの取得
    '(第1パラメータ:JNDI名, 第2パラメータ:module名.interface名)
    Set home = J2eebr.lookup("Sample", "ejbsample.SampleHome")
    
    homeオブジェクト名は rmicで生成したIDLの "module名"."interface名"になります。
    一般的にはEJBのフルパッケージ名が適用されますが、「Java to IDL Language Mapping」(OMG)の仕様に基づき、予約語や重複した名前は別名が適用される場合があります。

    module名とinterface名を確認するには、homeのIDLファイル(*Home.idl)を開き、以下の箇所を参照します。
    [homeのIDLファイル: *Home.idl]
    module ejbsample {
             ↑module名
    
        interface SampleHome: ::javax::ejb::EJBHome {
                      ↑interface名
    
  4. remoteオブジェクトの生成
    remoteオブジェクトを生成するには、次のようにhomeオブジェクトのメソッドを使用します。
    [VB6.0, VB.NET]
    '(VB.NETの場合、Setステートメントは不要)
    Dim remote As Object
    
    'remoteオブジェクトの生成
    Set remote = home.create()
    
  5. remoteオブジェクトメソッドの呼び出し
    remoteオブジェクトのメソッドを呼び出すには、次のようにhomeオブジェクトと同様にそのままメソッド名を使用します。
    メソッドの引数や戻り値で使用できる型とJavaからVisual Basicへのマッピングについては、[使用可能なデータ型]を参照してください。
    [VB6.0, VB.NET]
    'remoteメソッドの呼び出し
    Call remote.callMethod("hello")
    
  6. エラー処理
    EJBゲートウェイは実行時エラーが発生した場合にエラーメッセージと共にエラー番号を返却します。VB6.0の場合は、Err.Numberによりエラー番号を取得できますが、 VB.NETの場合にエラー番号を取得するには、Runtime.InteropServices.COMExceptionクラスのErrorCodeプロパティを使用します。
    [VB6.0]
    Private Sub Command1_Click()
    
        On Error GoTo Exception
            :
    
        Exit Sub
    
    Exception:
        'エラーメッセージとエラー番号の出力
        Call MsgBox(Err.Description & vbCr & "ErrCode:" & _
                Hex(Err.Number), vbExclamation)
    End Sub
    
    [VB.NET]
    Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
    
        Try
            :
    
        Catch ex As Runtime.InteropServices.COMException
            'エラーメッセージとエラー番号の出力
            MsgBox(ex.ToString & vbCr & "ErrCode:" & _
                Hex(ex.ErrorCode), MsgBoxStyle.Exclamation)
    
        Catch ex As Exception
            'エラーメッセージの出力
            MsgBox(ex.ToString, MsgBoxStyle.Exclamation)
    
        Finally
            :
        End Try
    End Sub
    

    Memo 実行時に発生したエラーメッセージの詳細については、 [例外一覧 > 5. CORBA > 5.4. CORBA, EJBゲートウェイのエラー一覧] を参照してください。

  7. 各オブジェクトの解放
    各オブジェクトが不要になった際は、Object型の変数に Nothingを代入してオブジェクトを解放します。
    VB.NETにおけるオブジェクトの解放は .NET Frameworkのガベージコレクトの発生まで遅延するため、即時にオブジェクトが解放されません。このため、VB.NETでオブジェクトを即時に解放する場合は System.Runtime.InteropServices.Marshal.FinalReleaseComObject()または、ReleaseComObject()により明示的にオブジェクトを解放するか、System.GC.Collect()によりガベージ コレクションを実行してください。
    [VB6.0]
    '各オブジェクトの解放
    Set remote = Nothing
    Set home = Nothing
    Set J2eebr = Nothing
    
    [VB 2005以降: 明示的に解放]
    Imports System.Runtime.InteropServices.Marshal
        :
    '各オブジェクトを明示的に解放
    If Not remote Is Nothing Then
        FinalReleaseComObject(remote)
        remote = Nothing
    End If
    If Not home Is Nothing Then
        FinalReleaseComObject(home)
        home = Nothing
    End If
    If Not J2eebr Is Nothing Then
        FinalReleaseComObject(J2eebr)
        J2eebr = Nothing
    End If
    
    [VB.NET 2003以前: 明示的に解放]
    Imports System.Runtime.InteropServices.Marshal
        :
    '各オブジェクトを明示的に解放
    If Not remote Is Nothing Then
        Do While ReleaseComObject(remote) > 0
        Loop
        remote = Nothing
    End If
    If Not home Is Nothing Then
        Do While ReleaseComObject(home) > 0
        Loop
        home = Nothing
    End If
    If Not J2eebr Is Nothing Then
        Do While ReleaseComObject(J2eebr) > 0
        Loop
        J2eebr = Nothing
    End If
    
    [VB.NET: GCにより解放]
    '各オブジェクトをGCにより解放
    remote = Nothing
    home = Nothing
    J2eebr = Nothing
    'ガベージ コレクション実行
    GC.Collect()
    

以上のまとめたサンプルコーディングを次に示します。

[VB6.0]
Private J2eebr As J2EE.Bridge       'J2EE.Bridgeオブジェクト
Private home As Object              'homeオブジェクト
Private remote As Object            'remoteオブジェクト

Private Sub Command1_Click()

    On Error GoTo Exception

    'J2EE.Bridgeオブジェクトの生成
    Set J2eebr = New J2EE.Bridge

    '名前サーバのURL設定(ポート番号の省略時は既定値の2809)
    Call J2eebr.setProviderURL("corbaname://localhost")

    'homeオブジェクトの取得
    '(第1パラメータ:JNDI名, 第2パラメータ:module名.interface名)
    Set home = J2eebr.lookup("Sample", "ejbsample.SampleHome")

    'remoteオブジェクトの生成
    Set remote = home.create()

    'remoteメソッドの呼び出し
    Call remote.callMethod("hello")

    GoTo Finally

Exception:
    'エラーメッセージとエラー番号の出力
    Call MsgBox(Err.Description & vbCr & "ErrCode:" & _
            Hex(Err.Number), vbExclamation)

Finally:
    '各オブジェクトの解放
    Set remote = Nothing
    Set home = Nothing
    Set J2eebr = Nothing
End Sub
[VB.NET]
Imports System.Runtime.InteropServices.Marshal

Private J2eebr As J2EE.Bridge       'J2EE.Bridgeオブジェクト
Private home As Object              'homeオブジェクト
Private remote As Object            'remoteオブジェクト

Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click

    Try
        'J2EE.Bridgeオブジェクトの生成
        J2eebr = New J2EE.Bridge

        '名前サーバのURL設定(ポート番号の省略時は既定値の2809)
        Call J2eebr.setProviderURL("corbaname://localhost")

        'homeオブジェクトの取得
        '(第1パラメータ:JNDI名, 第2パラメータ:module名.interface名)
        home = J2eebr.lookup("Sample", "ejbsample.SampleHome")

        'remoteオブジェクトの生成
        Call remote = home.create()

        'remoteメソッドの呼び出し
        Call remote.callMethod("hello")

    Catch ex As Runtime.InteropServices.COMException
        'エラーメッセージとエラー番号の出力
        MsgBox(ex.ToString & vbCr & "ErrCode:" & _
            Hex(ex.ErrorCode), MsgBoxStyle.Exclamation)

    Catch ex As Exception
        'エラーメッセージの出力
        MsgBox(ex.ToString, MsgBoxStyle.Exclamation)

    Finally
        '各オブジェクトの解放(明示的に解放)
        If Not remote Is Nothing Then
            FinalReleaseComObject(remote)
            remote = Nothing
        End If
        If Not home Is Nothing Then
            FinalReleaseComObject(home)
            home = Nothing
        End If
        If Not J2eebr Is Nothing Then
            FinalReleaseComObject(J2eebr)
            J2eebr = Nothing
        End If
    End Try
End Sub

9.6.2. 配列の使用方法

EJB側は通常のjavaの配列を使用します。

Javaの多次元配列([ , ]型)は使用できますが、ジャグ配列([ ][ ]型)と呼ばれる各次元の要素数が異なる配列は使用できません。

例えば文字列の一次元配列を使用する場合は次のように実装します。

[リモートインタフェースクラス]
public String[] LoopBackArrayString(String[] param1) throws RemoteException;
[Bean実装クラス]
public String[] LoopBackArrayString(String[] param1) {
    // System.outは対象domainのlogs\server.logに出力されます
    System.out.println("String[] - param1.length:" + param1.length);

    for (int i = 0; i < param1.length; i++) {
        System.out.println("param1[" + i + "]:" + param1[i]);
    }

    return param1;
}

Visual Basic側も通常の配列を使用しますが、出力パラメータに使用する場合は、次のように要素数なしの変数を宣言する必要があります。

[出力パラメータに使用する配列の宣言]
Dim paramOutArray() As String

入力パラメータのみに使用する場合は、次のように要素数付きで宣言できます。

[入力パラメータのみに使用する配列の宣言]
Dim paramInArray(3) As String

出力パラメータとして配列を受け取った場合は、UBound関数により配列の大きさを取得して、各要素にアクセスすることができます。

[VB6.0]
For i = 0 to UBound(paramOutArray)
    '要素の取得
    Debug.Print "paramOutArray(" & i & "):" & paramOutArray(i)
Next
[VB.NET]
For i = 0 to UBound(paramOutArray)
    '要素の取得
    Debug.WriteLine("paramOutArray(" & i & "):" & paramOutArray(i))
Next

以上のまとめたサンプルコーディングを次に示します。

[VB6.0]
Dim i As Integer
Dim paramOutArray() As String
Dim paramInArray(3) AS String

paramInArray(0) = "a"
paramInArray(1) = "b"
paramInArray(2) = "c"
paramInArray(3) = "d"

'remoteメソッドの呼び出し
paramOutArray = remote.LoopBackArrayString(paramInArray)

For i = 0 to UBound(paramOutArray)
    '要素の取得
    Debug.Print "paramOutArray(" & i & "):" & paramOutArray(i)
Next
[VB.NET]
    '(下から2行目のみ次の内容に変更)
    Debug.WriteLine("paramOutArray(" & i & "):" & paramOutArray(i))

9.6.3. ユーザ定義JavaBeanの使用方法

EJB側はユーザ定義型のBeanクラスを作成します。

例えばIDとパスワードを含むBeanクラスは次のように実装します。

[Beanクラス] account.java
public class account implements java.io.Serializable {
    private int id;
    private String password;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}
[リモートインタフェースクラス]
public boolean sampleValidation(account param1) throws RemoteException;
public account sampleSearch(int param1) throws RemoteException;
[Bean実装クラス]
public boolean sampleValidation(account param1) {

    System.out.println("account - param1:" + param1.getId() + ","
                                           + param1.getPassword());

    return (param1.getId() > 0 && param1.getPassword().length() > 2);
}

public account sampleSearch(int param1) {

    System.out.println("int - param1:" + param1);

    account ret = new account();
    ret.setId(param1);
    ret.setPassword("pass" + param1);
    return ret;
}

Visual Basicではpersonに対応する変数を次のようにObject型で宣言します。

入力パラメータで使用する場合は、次のようにJ2EE.BridgeオブジェクトのJavaNewメソッドでオブジェクトインスタンスを生成します。Object変数はBeanクラスのメンバをプロパティとして持つオブジェクトに初期化されます。

[VB6.0, VB.NET]
'(VB.NETの場合、Setステートメントは不要)
Dim J2eebr As J2EE.Bridge
Dim account As Object

'J2EE.Bridgeオブジェクトの生成
Set J2eebr = New J2EE.Bridge
'ユーザ定義型JavaBeanオブジェクトの生成
Set account = J2eebr.JavaNew("ejbsample.account")

クラス名は rmicで生成したIDLの "module名"."valuetype名"になります。

homeのクラス名と同様に対象クラスのIDLファイル("クラス名".idl)から参照できます。

[対象クラスのIDLファイル: "クラス名".idl]
module ejbsample {
         ↑module名

    valuetype account {
                ↑valuetype名

JavaNewにより生成したObject変数はBeanクラスのメンバに対応したプロパティにより、各メンバにアクセスできます。

[VB6.0, VB.NET]
'(VB.NETの場合、Setステートメントは不要)
Dim result As Boolean
'ユーザ定義型JavaBeanオブジェクトの生成
Set account = J2eebr.JavaNew("ejbsample.account")
'メンバに設定
account.id = 12345
account.password = "ejbgw"
'remoteメソッドの呼び出し
result = remote.sampleValidation(account)

返却値で使用する場合もObject型の変数を指定しますが、JavaNewによりインスタンス化する必要はありません。メソッド実行後に、オブジェクトインスタンスが生成され、メンバに値が設定されます。入力パラメータと同様にBeanクラスのメンバに対応したプロパティにより、各メンバにアクセスできます。

[VB6.0]
Dim account As Object
'remoteメソッドの呼び出し
Set account = remote.sampleSearch(123)
'ユーザ定義型JavaBeanオブジェクトのメンバを出力
Debug.Print "result:" & account.id & "," & account.password
[VB.NET]
Dim account As Object
'remoteメソッドの呼び出し
account = remote.sampleSearch(123)
'ユーザ定義型JavaBeanオブジェクトのメンバを出力
Debug.WriteLine("result:" & account.id & "," & account.password)

JavaNewにより生成したObject変数と返却値で使用したObject変数についても、不要になった際は、Object型の変数に Nothingを代入してオブジェクトを解放します。

VB.NETにおけるオブジェクトの解放は.NET Frameworkのガベージコレクトの発生まで遅延するため、即時にオブジェクトが解放されません。このため、VB.NETでオブジェクトを即時に解放する場合は System.Runtime.InteropServices.Marshal.FinalReleaseComObject()または、ReleaseComObject()により明示的にオブジェクトを解放するか、System.GC.Collect()によりガベージ コレクションを実行してください。

[VB6.0]
'オブジェクトの解放
Set account = Nothing
[VB 2005以降: 明示的に解放]
'オブジェクトを明示的に解放
Imports System.Runtime.InteropServices.Marshal

If Not account Is Nothing Then
    FinalReleaseComObject(account)
    account = Nothing
End If
[VB.NET 2003以前: 明示的に解放]
'オブジェクトを明示的に解放
Imports System.Runtime.InteropServices.Marshal

If Not account Is Nothing Then
    Do While ReleaseComObject(account) > 0
    Loop
    account = Nothing
End If
[VB.NET: GCにより解放]
'オブジェクトの解放(GCにより解放)
account = Nothing
'ガベージ コレクション実行
GC.Collect()

9.6.4. ネストしたJavaBeanの使用方法

JavaBeanのメンバにJavaBeanを使用する場合について説明します。

例えば前記のIDとパスワードを含むBeanクラスを含むBeanクラスは次のように実装します。

[Beanクラス] person.java
public class person implements java.io.Serializable {
    private String username;
    private account useraccount;

    public String getUsername() {
        return username;
    }
    public void setId(String username) {
        this.username = username;
    }
    public account getUseraccount() {
        return useraccount;
    }
    public void setUseraccount(account useraccount) {
        this.useraccount = useraccount;
    }
}

入力パラメータとしてJavaBean内のJavaBeanを使用する場合は、子のオブジェクトを生成してメンバの値を設定してから、親のオブジェクトメンバに代入します。

[VB6.0, VB.NET]
'(VB.NETの場合、Setステートメントは不要)
Dim J2eebr As J2EE.Bridge
Dim account As Object
Dim person As Object

'J2EE.Bridgeオブジェクトの生成
Set J2eebr = New J2EE.Bridge

'ユーザ定義型JavaBeanオブジェクトの生成
Set account = J2eebr.JavaNew("ejbsample.account")
'メンバに設定
account.id = 12345
account.password = "ejbgw"

'ユーザ定義型JavaBeanオブジェクトの生成
Set person = J2eebr.JavaNew("ejbsample.person")
'メンバに設定
person.username = "日電花子"
Set person.useraccount = account

出力パラメータとしてJavaBean内のJavaBeanを使用する場合は、子のオブジェクトをObject型の変数に取得し、そのオブジェクトに対するプロパティにより、各メンバにアクセスできます。

[VB6.0]
Dim account As Object
Dim person As Object

'子のユーザ定義型JavaBeanオブジェクトの取得
Set account = person.useraccount

'子のユーザ定義型JavaBeanオブジェクトのメンバを出力
Debug.Print "result:" & account.id & "," & account.password
[VB.NET]
Dim account As Object
Dim person As Object

'子のユーザ定義型JavaBeanオブジェクトの取得
account = person.useraccount

'子のユーザ定義型JavaBeanオブジェクトのメンバを出力
Debug.WriteLine("result:" & account.id & "," & account.password)

9.6.5. java.util.Date, Vectorの使用方法

EJBゲートウェイはjava.lang.Stringの文字列以外のJavaBeanとして、java.util.Datejava.util.Vectorをサポートしています。それぞれのサポート内容は次のとおりです。

具体的な使用方法を以下に説明します。

EJB側は通常のjava.util.Datejava.util.Vectorをそのまま使用します。
例えば両者を使用する場合は次のように実装します。

[リモートインタフェースクラス]
import java.util.*;

public Date LoopBackDate(Date param1) throws RemoteException;
public Vector LoopBackVector(Vector param1) throws RemoteException;
[Bean実装クラス]
import java.text.*;
import java.util.*;

private static final DateFormat df = new
                        SimpleDateFormat("yy/MM/dd HH:mm:ss.SSS");

public Date LoopBackDate(Date param1) {
    // System.outは対象domainのlogs\server.logに出力されます
    System.out.println("Date - param1:" + df.format(param1)
        + ", getTime():" + param1.getTime());
    return param1;
}

public Vector LoopBackVector(Vector param1) {
    if (param1 != null) {
        // System.outは対象domainのlogs\server.logに出力されます
        System.out.println("Vector - param1.size:"
            + param1.size());

        // 値の列挙
        Iterator Enum = param1.iterator();
        int i = 0;
        Object obj;

        // Iterator内の要素を列挙する
        while (Enum.hasNext()) {
            obj = Enum.next();
            if (obj != null) {
                System.out.println("param1[" + i + "]"
                     + obj.getClass().getName() + ":" + obj);
            } else {
                System.out.println("param1[" + i + "]null");
            }
            i++;
        }
    }
    return param1;
}

Visual Basicでは、java.util.Dateに対応する変数をDate型で宣言します。

java.util.Vectorに対応する変数をVB6.0ではVariantの配列、VB.NETではObjectの配列として使用できますが、入力パラメータで使用する場合は、要素数付きで宣言できます。また、出力パラメータで使用する場合は、配列を省略して宣言できます。

[VB6.0]
'java.util.Date用
Dim paramInDate As Date
Dim paramOutDate As Date
'java.util.Vector用
Dim paramInVector(3) As Variant
Dim paramOutVector As Variant
[VB.NET]
'java.util.Date用
Dim paramInDate As Date
Dim paramOutDate As Date
'java.util.Vector用
Dim paramInVector(3) As Object
Dim paramOutVector As Object

出力パラメータとしてjava.util.Vectorに対応する配列を受け取った場合は、UBound関数により配列の大きさを取得して、各要素にアクセスすることができます。

[VB6.0]
For i = 0 to UBound(paramOutVector)
    '要素の取得
    Debug.Print "paramOutVector(" & i & "):" & paramOutVector(i)
Next
[VB.NET]
For i = 0 to UBound(paramOutVector)
    '要素の取得
    Debug.WriteLine("paramOutVector(" & i & "):" & paramOutVector(i))
Next

以上のまとめたサンプルコーディングを次に示します。

[VB6.0]
Dim i As Integer
'java.util.Date用
Dim paramInDate As Date
Dim paramOutDate As Date
'java.util.Vector用
Dim paramInVector(3) As Variant
Dim paramOutVector As Variant

paramInDate = CDate("2345/12/23 12:34:56")

'java.util.Date用remoteメソッドの呼び出し
paramOutDate = remote.LoopBackDate(paramInDate)

'java.util.Date用 戻り値の確認
Debug.Print "paramOutDate:" & paramOutDate

paramInVector(0) = "abc"
paramInVector(1) = 10
paramInVector(2) = 20!
paramInVector(3) = 30&

'java.util.Vector用remoteメソッドの呼び出し
paramOutVector = remote.LoopBackVector(paramInArrayVector)

'java.util.Vector用 戻り値の確認
For i = 0 to UBound(paramOutVector)
    '要素の取得
    Debug.Print "paramOutVector(" & i & "):" & paramOutVector(i)
Next
[VB.NET]
Dim i As Integer
'java.util.Date用
Dim paramInDate As Date
Dim paramOutDate As Date
'java.util.Vector用
Dim paramInVector(3) As Object
Dim paramOutVector As Object

paramInDate = CDate("2345/12/23 12:34:56")

'java.util.Date用remoteメソッドの呼び出し
paramOutDate = remote.LoopBackDate(paramInDate)

'java.util.Date用 戻り値の確認
Debug.WriteLine("paramOutDate:" & paramOutDate)

paramInVector(0) = "abc"
paramInVector(1) = 10
paramInVector(2) = 20!
paramInVector(3) = 30&

'java.util.Vector用remoteメソッドの呼び出し
paramOutVector = remote.LoopBackVector(paramInVector)

'java.util.Vector用 戻り値の確認
For i = 0 to UBound(paramOutVector)
    '要素の取得
    Debug.WriteLine("paramOutVector(" & i & "):" & paramOutVector(i))
Next

9.6.6. ユーザ定義例外の使用方法

EJB側はjava.lang.Exceptionを継承したユーザ定義型の例外クラスを作成します。

例えばmessageを引数に持つコンストラクタを持つユーザ定義例外は次のように実装します。

リモートインタフェースとBean実装クラスに、throws UserExceptionを追加して、この例外をスローできるようにします。

[ユーザ定義例外クラス] UserException.java
public class UserException extends Exception {

    public UserException(String message) {
        super(message + " at " + new java.util.Date());
    }
}
[リモートインタフェースクラス]
public boolean sampleValidation(account param1) throws
                            RemoteException, UserException;
[Bean実装クラス]
public boolean sampleValidation(account param1) throws UserException {

    System.out.println("account - param1:" + param1.getId() + ","
                                           + param1.getPassword());

    if (param1.getId() < 0)
        throw new UserException("IDに負の値が検出されました");

    return (param1.getId() > 0 && param1.getPassword().length() > 2);
}

VB6.0の On Error ステートメントで指定したエラー処理 および、VB.NETの Catchステートメントで Runtime.InteropServices.COMExceptionを検出した際に、J2EE.Bridgeオブジェクトの getExceptionメソッドを使用して ユーザ定義例外のオブジェクトを取得します。

VB のTypeName関数により、ユーザ定義例外のオブジェクトからクラス名を取得することができます。サーバ側で例外メッセージを設定している場合、ユーザ定義例外のオブジェクトの Messageプロパティで内容を参照することができます。

[VB6.0]
Private Sub Command1_Click()

    On Error GoTo Exception

    'remoteメソッドの呼び出し
    Call remote.sampleValidation()
    Exit Sub

Exception:
    '例外オブジェクトの取得
    Dim J2eeEx As Object
    Set J2eeEx = J2eebr.getException(remote)

    If Not J2eeEx Is Nothing Then
        'ユーザ定義例外がある場合
        Call MsgBox(J2eeEx.Message & vbCr & "Class:" & _
                TypeName(J2eeEx), vbExclamation)

        'ユーザ定義毎の処理を行う場合
        Select Case TypeName(J2eeEx)
            Case "ejbsample.UserException"
                :
            Case "ejbsample.UserException2"
                :
        End Select
    Else
        Call MsgBox(Err.Description & vbCr & "ErrCode:" & _
                Hex(Err.Number), vbExclamation)
    End If
End Sub
[VB.NET]
Try
    'remoteメソッドの呼び出し
    remote.sampleValidation()

Catch ex As Runtime.InteropServices.COMException

    '例外オブジェクトの取得
    Dim J2eeEx As Object
    J2eeEx = J2eebr.getException(remote)

    If Not J2eeEx Is Nothing Then
        'ユーザ定義例外がある場合
        MsgBox(J2eeEx.Message & vbCr & "Class:" & _
            TypeName(J2eeEx), MsgBoxStyle.Exclamation)

        'ユーザ定義毎の処理を行う場合
        Select Case TypeName(J2eeEx)
            Case "ejbsample.UserException"
                :
            Case "ejbsample.UserException2"
                :
        End Select
    Else
        MsgBox(ex.ToString & vbCr & "ErrCode:" & _
            Hex(ex.ErrorCode), MsgBoxStyle.Exclamation)
    End If

Catch ex As Exception
    MsgBox(ex.ToString, MsgBoxStyle.Exclamation)
End Try

9.7. Visual Basic .NETにおける注意点

オブジェクト代入処理の違い

VB.NETでは、Setステートメントが不要のため、オブジェクトの代入処理に次のような違いがあります。

[VB6.0]
Dim J2eebr As J2EE.Bridge

'J2EE.Bridgeオブジェクトの生成
Set J2eebr = New J2EE.Bridge
[VB.NET]
Dim J2eebr As J2EE.Bridge

'J2EE.Bridgeオブジェクトの生成
J2eebr = New J2EE.Bridge

オブジェクト解放のタイミングの違い

VB.NETにおけるNothing代入によるオブジェクトの解放は .NET Frameworkのガベージコレクトの発生まで遅延するため、即時にオブジェクトが解放されません。これによりクライアントリソースが減少するだけでなく、クライアントとアプリケーションサーバ間のコネクション持続時間が長くなり、アプリケーションサーバに同時に接続できるクライアントアプリケーション数が減少することがあります。

このため、VB.NETでオブジェクトを即時に解放する場合は System.Runtime.InteropServices.Marshal.FinalReleaseComObject()または、ReleaseComObject()により明示的にオブジェクトを解放するか、System.GC.Collect()によりガベージ コレクションを実行してください。

[VB 2005以降: 明示的に解放]
Imports System.Runtime.InteropServices.Marshal
    :
'各オブジェクトを明示的に解放
If Not remote Is Nothing Then
    FinalReleaseComObject(remote)
    remote = Nothing
End If
If Not home Is Nothing Then
    FinalReleaseComObject(home)
    home = Nothing
End If
If Not J2eebr Is Nothing Then
    FinalReleaseComObject(J2eebr)
    J2eebr = Nothing
End If
[VB.NET 2003以前: 明示的に解放]
Imports System.Runtime.InteropServices.Marshal
    :
'各オブジェクトを明示的に解放
If Not remote Is Nothing Then
    Do While ReleaseComObject(remote) > 0
    Loop
    remote = Nothing
End If
If Not home Is Nothing Then
    Do While ReleaseComObject(home) > 0
    Loop
    home = Nothing
End If
If Not J2eebr Is Nothing Then
    Do While ReleaseComObject(J2eebr) > 0
    Loop
    J2eebr = Nothing
End If
[VB.NET: GCにより解放]
'各オブジェクトをGCにより解放
remote = Nothing
home = Nothing
J2eebr = Nothing
'ガベージ コレクション実行
GC.Collect()

マルチスレッドプログラムからの同時アクセスについて

マルチスレッドプログラムから同時アクセスする場合、スレッド開始前にスレッドモデルをSTA(シングルスレッドアパートメント)に設定する必要があります。特に、.NET Framework 2.0以降(Visual Basic 2005以降)の場合、スレッドモデルの既定値は MTA(マルチスレッドアパートメント)であるため、Thread.SetApartmentStateメソッドにより、STAに設定する必要があります。マルチスレッド および、スレッドモデルの詳細については、マイクロソフトの技術資料(MSDNなど)を参照してください。

[VB 2005以降]
Imports System.Threading
    :
'スレッドを準備
Dim th As New Thread(AddressOf ThreadProc)
'スレッドモデルをSTAに設定
th.SetApartmentState(ApartmentState.STA)
'スレッド開始
th.Start()
    :

'スレッドの実行開始メソッド
Sub ThreadProc()
    'スレッドのApartmentStateを表示
    MsgBox("ApartmentState(0:STA, 1:MTA, 2:Unknown)=" & _
        Thread.CurrentThread.GetApartmentState())
End Sub
[VB.NET 2003以前]
Imports System.Threading
    :
'スレッドを準備
Dim th As New Thread(AddressOf ThreadProc)
'スレッドモデルをSTAに設定
th.ApartmentState = ApartmentState.STA
'スレッド開始
th.Start()
    :

'スレッドの実行開始メソッド
Sub ThreadProc()
    'スレッドのApartmentStateを表示
    MsgBox("ApartmentState(0:STA, 1:MTA, 2:Unknown)=" & _
        Thread.CurrentThread.ApartmentState)
End Sub

9.8. EJB3.0アプリケーションの適用

EJBゲートウェイはEJB 2.x仕様に基づくホームインタフェースが必要であるため、EJB 3.0アプリケーションを適用するには、EJB 3.0と2.xを組み合わせた形式(以下、EJB 3.0/2.x形式と略す)にする必要があります。

EJB3.0/2.x形式のサーバアプリケーションはEJB2.xのサーバアプリケーションと同様にEJBゲートウェイから呼び出すことができます。

EJB 3.0アプリケーションからEJB 3.0/2.x形式のサーバアプリケーションを作成するには、以下の対応が必要になります。

  1. EJB 2.x用のホームインタフェースとリモートインタフェースを追加
  2. アノテーション@Remote、@RemoteHomeのインタフェースの関連付け
  3. アノテーション@Statelessや@Statefulに明示的なJNDI物理名を指定
  4. Bean本体へのejbCreateメソッド追加

EJB 2.x用のホームインタフェースとリモートインタフェースは以下のように作成します。基本的にEJB 2.xと同様になりますが、ホームインタフェースでcreateするものは、EJB 2.x用のリモートインタフェースになります。

[EJB 2.x用ホームインタフェース]
import java.rmi.RemoteException;

public interface TypeTestHome extends EJBHome {
    public TypeTest2x create() throws CreateException, RemoteException;
            ↑EJB 2.x用リモートインタフェース
}
[EJB 2.x用リモートインタフェース]
public interface TypeTest2x extends EJBObject {
    public byte LoopBackByte(byte param1) throws RemoteException;
}

@Remote、@RemoteHomeのインタフェースの関連付けと @Statelessや @Statefulに明示的なJNDI名の指定は、Bean本体でします。以下のように、@RemoteにEJB 3.0用のビジネスインタフェース、@RemoteHome に EJB 2.x用のホームインタフェースをそれぞれ関連付けます。

@RemoteHomeを付与した場合、既定値のJNDI物理名が付与されません。そのため、@Statelessや@StatefulにJNDI物理名を指定する必要があります。このJNDI物理名がhomeオブジェクトをlookupで取得するときのJNDI名になります。また、ejbCreateメソッドも追加する必要があります。

[EJB 3.0 Bean本体]
// JNDI物理名を指定
@Stateless(mappedName="TypeTest")
// EJB 3.0用ビジネスインタフェースの関連付け
@Remote(TypeTest.class)
// EJB 2.x用ホームインタフェースの関連付け
@RemoteHome(TypeTestHome.class)
public class TypeTestBean implements TypeTest {

    // ejbCreateメソッドの追加
    public void ejbCreate() {}

    public byte LoopBackByte(byte param1) {
        return param1;
    }
}

Memo EJBゲートウェイのサンプルに EJB 3.0/2.x形式のサンプルも格納しています。

9.9. 負荷分散の設定

WebOTXはスケーラビリティを向上するためにサーバを複数台使用して負荷分散運用を行うことができます。ここでは負荷分散運用を導入する方法について説明します。

EJBアプリケーションの負荷分散を導入するには、次のような設定が必要になります。

対 象 設定内容 概 要
負荷分散装置 WebOTXが使用する2つのポート番号の設定 2809
EXP
ExpressとDeveloperのテストサーバは7780
STDENT
Standard, Enterpriseは5151
Object Broker 「クライアント端末に公開するホスト名」に仮想サーバのホスト名を設定 統合運用管理ツール または、運用管理コマンドから設定
TPシステム 「接続サーバ名」に仮想サーバのホスト名を設定 STDENT
Standard, Enterpriseの場合のみ設定
名前サーバ 配備済みのアプリケーションがある場合、登録情報を削除 namesv.ndfを削除
EJBゲートウェイ 名前サーバのURLに仮想サーバのホスト名を設定 setProviderURLで仮想サーバのホスト名を設定

Memo DNSのない環境で仮想サーバ名を使用するには、サーバとクライアント両方のhostsファイルに仮想サーバ名の設定が必要になります。

以下にそれぞれの詳細について説明します。

負荷分散装置の設定

WebOTXと負荷分散装置を組み合わせて運用できるようにするため、WebOTXが通信に使用するポート番号を負荷分散装置に設定する必要があります。以下に設定が必要なポート番号について説明します。

ポート番号 説 明
2809 名前サーバに対してオブジェクトリファレンスを要求するポート番号
7780 または、5151 IIOPリスナに対してEJBのメソッドを呼び出すポート番号
EXP
ExpressとDeveloperのテストサーバの既定値は7780
STDENT
Standard, Enterpriseの既定値は5151

設定方法については、負荷分散装置のマニュアルを参照してください。

Object Brokerの設定

オブジェクトリファレンスに設定するホスト名に、負荷分散装置の仮想サーバ名を設定する必要があります。以下に統合運用管理ツールと運用管理コマンドによる設定方法について説明します。

統合運用管理ツールから設定
左パネルから対象ドメインの[アプリケーションサーバ]/[Object Brokerコンフィグ]を選択し、右パネルの[共通]タブ内にある[クライアント端末に公開するホスト名]に仮想サーバ名を設定します。

運用管理コマンドから設定
対象ドメインにログインし、以下のコマンドを入力します。

Object Brokerの設定コマンド
set server.objectbrokerconfig.ExternalHostName=<仮想サーバ名>
[例] 仮想サーバ名が serverの場合
otxadmin> set server.objectbrokerconfig.ExternalHostName=server

TPシステムの設定 STDENT

Standard および、Enterpriseの場合は、TPシステムの接続サーバ名を負荷分散装置の仮想サーバ名に設定する必要があります。以下に統合運用管理ツールと運用管理コマンドによる設定方法について説明します。

統合運用管理ツールから設定
左パネルから対象ドメインの[TPシステム]を選択し、右パネルの[システム情報]タブ内にある[接続サーバ名]に仮想サーバ名を設定します。

運用管理コマンドから設定
対象ドメインにログインし、以下のコマンドを入力します。

TPシステムの設定コマンド
set WebOTXSystem.serverName=<仮想サーバ名>
[例] 仮想サーバ名が serverの場合
otxadmin> set WebOTXSystem.serverName=server

名前サーバの登録情報を削除

仮想サーバ名を設定する前に名前サーバに登録した情報には、実サーバ名の情報が登録されているため、仮想サーバ名を設定する前に配備したアプリケーションがある場合、名前サーバの登録情報を削除する必要があります。以下の手順で名前サーバの登録情報を削除してください。

  1. ドメインを停止
    対象のドメインを停止してください。

    起動・停止方法については、 [ドメイン構築・基本設定ガイド > 3. ドメイン > 3.4. ドメインの起動・停止] を参照してください。

  2. 名前サーバの登録情報を削除
    unixはpsコマンドで、Windowsはタスクマネージャ等で、namesvとoadのプロセスが存在しないことを確認し、次のファイルをバックアップ用に退避した後、削除してください。
    <WebOTXインストールディレクトリ>/domains/<対象ドメイン名>/config/ObjectBroker/namesv.ndf

  3. ドメインを起動
    対象のドメインを起動してください。

    名前サーバの登録情報を削除したため、配備済みのサーバアプリケーションについては、再度名前サーバへ登録する必要があります。

EJBゲートウェイの設定

EJBゲートウェイでは setProviderURLで指定する名前サーバのURLに、負荷分散装置の仮想サーバのホスト名を設定する必要があります。

setProviderURLについては、[プログラミング・開発ガイド]を参照してください。

9.10. SSL通信の設定 STDENT

WebOTX Application ServerのStandard および、Enterpriseはクライアントとサーバ間の通信にSSL (Secure Socket Layer) を適用し、通信先(クライアント/サーバ)の認証と電文の暗号化を行うことができます。

ここでは、EJBゲートウェイを使用する環境にSSLを適用する方法について説明します。

SSLを適用するには、次のような設定が必要になります。

  1. サーバ環境−SSL通信機能(IIOP over SSL)のインストール
  2. サーバ環境−IIOPリスナのSSL設定
  3. 開発環境−EJBのSSL設定
  4. クライアント環境−SSL通信機能(IIOP)のインストール
  5. クライアント環境−信頼できるCAの証明書ファイルの指定

以下にそれぞれの詳細について説明します。

サーバ環境−SSL通信機能(IIOP over SSL)のインストール

WebOTX Application ServerのStandard および、Enterpriseインストール時に[カスタムセットアップ]を選択し、[IIOP over SSL]を追加します。

サーバ環境−IIOPリスナのSSL設定

統合運用管理ツールの[TPシステム]-[IIOPリスナ]でSSLのポート番号および、SSLサーバ証明書を設定します。設定を適用させるにはTPシステムの停止/起動が必要です。

  1. TPシステムを停止します。

  2. 該当するドメインの[TPシステム]-[IIOPリスナ]を選択します。


  3. [SSL]タブ内の[SSLを使用する]チェックボックスをオンにします。
    [SSL]タブ内の[クライアント認証なしのSSLを利用する]のチェックボックスをオンにし、次項目のポート番号に未使用なポート番号を指定します。
    クライアント認証を使用する場合は、[SSL]タブ内の[クライアント認証ありのSSLを利用する]のチェックボックスをオンにし、次項目のポート番号に未使用なポート番号を指定します。
    OSがWindowsの場合、ポート番号は5001〜32767の範囲で指定してください。


  4. <WebOTXインストールディレクトリ>\domains\<ドメイン名>\config\tpsystem配下に秘密鍵ファイル、証明書ファイル、信頼するCAの証明書ファイルを配置します。

  5. [OpenSSL]タブ内の[秘密鍵ファイル名], [証明書ファイル名], [信頼するCAの証明書ファイル名]にそれぞれのファイル名を指定します(フルパスで指定することはできません)。証明書はPEM形式のみ使用できます。


  6. 設定完了後、更新ボタンを押します。

  7. TPシステムを起動します。
開発環境−EJBのSSL設定

EJBに対するSSLの設定方法について説明します。

対象のEJBプロジェクトのMETA-INF配下にnec-ejb-jar.xmlファイルを作成します。
次に、作成したnec-ejb-jar.xmlをテキストエディタなどで開き、以下の記述をコピーして貼り付け、<ejb-name>と <jndi-name>要素にプロジェクトのEJB名とJNDI名を適用します。

[nec-ejb-jar.xmlファイル]
<?xml version="1.0" encoding="UTF-8"?>
<nec-ejb-jar>
  <enterprise-beans>
    <ejb>
      <!-- ↓プロジェクトのEJB名とJNDI名 -->
      <ejb-name>EJB名</ejb-name>
      <jndi-name>JNDI名</jndi-name>
      <ior-security-config>
        <transport-config>
          <integrity>REQUIRED</integrity>
          <confidentiality>REQUIRED</confidentiality>
          <establish-trust-in-target>SUPPORTED</establish-trust-in-target>
          <establish-trust-in-client>SUPPORTED</establish-trust-in-client>
        </transport-config>
      </ior-security-config>
    </ejb>
  </enterprise-beans>
</nec-ejb-jar>

クライアント環境−SSL通信機能(IIOP)のインストール

クライアント側でもSSL通信機能(IIOP)をインストールする必要があります。

このインストーラーは、<WebOTX Clientの収録媒体>\CLI\OTXOPSSL.msiにあります。なお、インストール後、PATH環境変数に <SSL通信機能(IIOP)インストールディレクトリ>\Trnsv\binを追加する必要があります。

クライアント環境−信頼できるCAの証明書ファイルの指定

クライアント側の設定としては、信頼できるCAの証明書を格納したファイルの設定が必要になります。サポートしている証明書はPEM形式のみです(例: cert.pem)。

信頼できるCAの証明書を格納したファイルを設定するには、次のレジストリ内容を適用してください(値がない場合は作成してください)。

レジストリキー HKEY_LOCAL_MACHINE\SOFTWARE\NEC\ObjectSpinner\1
名 前 種 類 値(既定値)
TrustedCACerts 文字列
(REG_SZ)
信頼できるCAの証明書ファイルをフルパスで指定(既定値: 定義なし)
サポートしている証明書はPEM形式のみです。

その他、サーバ側のSSL設定によってはクライアント証明書が必要になることもあります。詳細については、 [リファレンス集 運用管理・設定編 > 1. コンフィグレーション(設定一覧) > 1.10.3. Object Broker C++ における環境設定] 内の[OpenSSL 関連のオプション設定]を参照してください。

9.11. CSIv2の使用方法 STDENT

EJBゲートウェイはCSIv2 (Common Secure Interoperability Version 2) 仕様のGSSUP (Generic Security Services Username Password) をサポートしています。これにより、ユーザ認証によるアクセス制御ができるようになります。

この機能の使用には、WebOTX Application ServerのStandard および、EnterpriseのSSL通信の設定が必要になります。 SSLの詳細については、[SSL通信の設定]を参照してください。

ここでは、EJBゲートウェイでCSIv2を使用する方法について説明します。

CSIv2を使用するには、次のような設定が必要になります。

  1. サーバアプリケーション側 - ロールベースアクセス制御の設定
  2. クライアントアプリケーション側 - EJBゲートウェイで認証情報を設定

以下にそれぞれの詳細について説明します。

サーバアプリケーション側 - ロールベースアクセス制御の設定

ロールを定義し、EJBのメソッドに対してアクセスを許可するロールを設定します。また、ロールに割り当てるWebOTXユーザ または、グループを設定します。

Memo WebOTXユーザとグループの作成方法については、 [ドメイン構築・基本設定ガイド > 4. ユーザ管理 > 4.3.1. Fileレルムを使用する場合] を参照してください。

EJB2.xとEJB3.0では設定方法が異なります。以下にそれぞれの設定方法を説明します。

EJB 3.0の場合
  1. 対象のEJBプロジェクトのEJB Bean本体のファイルを開きます。
  2. EJBのBean本体にアノテーションを指定します。
    DeclareRolesアノテーションで使用するロールを定義し、RolesAllowedアノテーションでアクセス許可するロールを定義します。RolesAllowedアノテーションはクラスレベルで指定した場合は、全メソッドにアクセス許可を与え、メソッドレベルで指定した場合は、該当するメソッドに対してアクセス許可を与えます。
    [EJB 3.0 Bean本体]
    import javax.annotation.security.*;
    
    @Stateless(mappedName="TypeTest")
    @Remote(TypeTest.class)
    @RemoteHome(TypeTestHome.class)
    // ロールの定義
    @DeclareRoles("ロール名")
    // アクセス許可するロールを定義(クラスレベル)
    @RolesAllowed("ロール名")
    public class TypeTestBean implements TypeTest {
    
        public void ejbCreate() {}
    
        // アクセス許可するロールを定義(メソッドレベル)
        @RolesAllowed("ロール名")
        public byte LoopBackByte(byte param1) {
            return param1;
        }
    }
    
  3. 対象のEJBプロジェクトのMETA-INF配下にあるnec-ejb-jar.xmlファイルをテキストエディタなどで開きます。
  4. <security-role-mapping>要素を追加し、ロールに割り当てるユーザを設定します。<ejb-name>と <jndi-name>要素にはプロジェクトのEJB名とJNDI名を適用します。
    [nec-ejb-jar.xmlファイル]
    <?xml version="1.0" encoding="UTF-8"?>
    <nec-ejb-jar>
      <security-role-mapping>
        <!-- ↓ロール名 -->
        <role-name>ロール名</role-name>
        <!-- ↓このロールに割り当てるWebOTXユーザ(複数可) -->
        <principal-name>ユーザ名</principal-name>
        <!-- ↓このロールに割り当てるWebOTXグループ(複数可) -->
        <group-name>グループ名</group-name>
      </security-role-mapping>
      <enterprise-beans>
        <name>TypeTest</name>
        <ejb>
          <!-- ↓プロジェクトのEJB名とJNDI名 -->
          <ejb-name>EJB名</ejb-name>
          <jndi-name>JNDI名</jndi-name>
          <ior-security-config>
            <transport-config>
              <integrity>REQUIRED</integrity>
              <confidentiality>REQUIRED</confidentiality>
              <establish-trust-in-target>SUPPORTED</establish-trust-in-target>
              <establish-trust-in-client>SUPPORTED</establish-trust-in-client>
            </transport-config>
          </ior-security-config>
        </ejb>
      </enterprise-beans>
    </nec-ejb-jar>
    
EJB 2.xの場合
  1. 対象のEJBプロジェクトのMETA-INF配下にあるejb-jar.xmlファイルをテキストエディタなどで開きます。
  2. ejb-jar.xmlに<security-role>要素を追加して使用するロールを定義します。また、<method-permission>要素内に<role-name>要素を使用してアクセス許可するロールを定義します。
    以下はEJB 2.1を例にしたサンプルです。<ejb-name>と <jndi-name>要素にはプロジェクトのEJB名とJNDI名を適用します。このサンプルでは、ロールを定義し、そのロールに全メソッドのアクセス許可を与えています。
    [ejb-jar.xmlファイル]
    <?xml version="1.0" encoding="UTF-8"?>
    <ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
      <display-name xml:lang="ja">TypeTest</display-name>
      <enterprise-beans>
        <session>
          <display-name xml:lang="ja">TypeTest</display-name>
          <ejb-name>TypeTest</ejb-name>
          <home>sample.TypeTestHome</home>
          <remote>sample.TypeTest</remote>
          <ejb-class>sample.TypeTestBean</ejb-class>
          <session-type>Stateless</session-type>
          <transaction-type>Container</transaction-type>
        </session>
      </enterprise-beans>
      <assembly-descriptor>
        <security-role>
          <!-- ↓ロールの定義 -->
          <role-name>ロール名</role-name>
        </security-role>
        <method-permission>
          <!-- ↓アクセス許可するロールを定義 -->
          <role-name>ロール名</role-name>
          <method>
            <ejb-name>TypeTest</ejb-name>
            <!-- ↓全メソッドを対象 -->
            <method-name>*</method-name>
          </method>
        </method-permission>
      </assembly-descriptor>
    </ejb-jar>
    

    メソッド別にアクセス許可を設定する場合は、次のように <method-permission>要素内の<method-name>要素に対象のメソッドを定義してください。

    [ejb-jar.xmlファイル:メソッド毎の設定]
        <method-permission>
          <!-- ↓アクセス許可するロールを定義 -->
          <role-name>ロール名</role-name>
          <method>
            <ejb-name>TypeTest</ejb-name>
            <!-- ↓指定メソッドを対象 -->
            <method-name>メソッド名</method-name>
          </method>
        </method-permission>
    
  3. ロールに割り当てるユーザを設定します。設定方法はEJB 3.0と同じです。EJB 3.0の手順−3.以降を参照してください。
クライアントアプリケーション側 - EJBゲートウェイで認証情報を設定

EJBゲートウェイに認証情報を設定するには、以下のようにJ2EE.Bridgeの setInitialContextToken使用します。setInitialContextTokenの第3引数にEJBのhome または、remoteオブジェクトを指定した場合、そのオブジェクトのメソッドのみが対象になります。省略した場合は、全メソッドが対象になります。

[VB6.0, VB.NET]
'(VB.NETの場合、Setステートメントは不要)
Dim J2eebr As J2EE.Bridge           'J2EE.Bridgeオブジェクト
Dim home As Object                  'homeオブジェクト
Dim remote As Object                'remoteオブジェクト
Set J2eebr = New J2EE.Bridge()

'全メソッドを対象に認証情報を設定
Call J2eebr.setInitialContextToken("username", "password")

<中略>

'remoteオブジェクトの生成
Set remote = home.create()
'remoteオブジェクトのメソッドを対象に認証情報を設定
Call J2eebr.setInitialContextToken("username", "password", remote)

9.12. コマンドリファレンス

IFコンパイラ (woifgenコマンド) の使用方法を説明します。

形 式 woifgen { /ta | /u | /c } [IFファイル名] [/s]
機 能 CORBAゲートウェイ, EJBゲートウェイ用制御ファイルの生成、登録、削除
オプション /ta(省略可) IFファイル名
IFファイルから制御ファイルを生成し、レジストリに登録します。
/u IFファイル名
IFファイルに関する登録済みの情報をレジストリから削除します。
/c
レジストリを全て検索し、制御ファイルがないなどの整合性のとれていない登録済みの情報をレジストリから削除します。削除したレジストリ情報は wo{yymmdd}.regファイルにバックアップします。
/s
コマンド実行時に、ポップアップウィンドウの表示を抑制します。
終了コード 終了コードはバッチプログラム内で環境変数 %ERRORLEVEL%により確認できます。 終了コードが200番台の場合、woifgen.logにスタックトレースが出力されます。
4
レジストリ登録失敗。
100
正常終了。
101
指定された入力ファイルが存在しません。
102
指定されたIDLに使用できない型が定義されています。
103
GC1ファイルかTLBファイルが使用中のためアクセスできません。
104
GC1ファイルかTLBファイルを生成できません。
105
指定された入力ファイルが不正な形式です。
106
IDLで定義された継承元定義がありません。
200
WOFileExceptionが発生しました。woifgen.logを採取してください。
201
WOMemoryExceptionが発生しました。woifgen.logを採取してください。
202
WORangeExceptionが発生しました。woifgen.logを採取してください。
203
WOInvalidPathExceptionが発生しました。woifgen.logを採取してください。
204
WOExceptionが発生しました。woifgen.logを採取してください。
205
CExceptionが発生しました。woifgen.logを採取してください。

Caution

9.13. 障害時のトレース取得方法

障害が発生した場合は、調査のためトレースファイルを採取してください。

クライアントアプリケーション実行時に障害が発生した場合、EJBゲートウェイと Object Broker C++のトレースが必要になります。

IFコンパイル実行時に障害が発生した場合、IFコンパイラのトレースが必要になります。

EJBゲートウェイのトレース

EJBゲートウェイのデバッグトレースを採取するには、次のレジストリ内容を適用してください(キーや値がない場合は作成してください)。

レジストリキー HKEY_LOCAL_MACHINE\Software\NEC\WebOTX\EJBGW
名 前 種 類 値(既定値)
TraceLevel DWORD
(REG_DWORD)
7 (既定値: 5)

トレースファイルは作業フォルダ(カレントディレクトリ)内のejbgw.logに出力されます。

Memo エラー内容の詳細については、 [例外一覧 > 5. CORBA > 5.4. CORBA, EJBゲートウェイのエラー一覧] を参照してください。

ファイルサイズの上限やファイル名を変更する場合は、次のレジストリ内容を適用してください(キーや値がない場合は作成してください)。

レジストリキー HKEY_LOCAL_MACHINE\Software\NEC\WebOTX\EJBGW
名 前 種 類 値(既定値)
TraceFilename 文字列
(REG_SZ)
取得するトレースファイル名(既定値: ejbgw.log
255文字以内の文字列を設定します。
出力先の既定値は作業フォルダ(カレントディレクトリ)です。出力先を変更するには、ファイル名をフルパスで指定してください。
TraceSize DWORD
(REG_DWORD)
トレースサイズの上限(既定値: 64Kバイト)
トレースサイズの上限をKバイト単位で設定します。この上限を超えると、ファイル名の末尾に「.bak」を付加してバックアップし、新しいトレースファイルを作成します。
TraceMulti DWORD
(REG_DWORD)
プロセス別にトレースファイルを分割する
0
トレースファイルを分割しない(既定値)
1
トレースファイル名にプロセス番号を付加して、プロセス毎にトレースファイルを作成する

Caution
Windows Vista以降でUAC(ユーザアカウント制御)が有効の場合、ログファイルの出力先はユーザプログラムのマニフェストファイルやフォルダの権限により、次のように異なります。
ユーザプログラムの
マニフェストの有無
ユーザプログラムの
作業フォルダ権限
ログファイルの出力先
マニフェスト あり マニフェスト内の実行権限による書き込み権限 あり ユーザプログラムの作業フォルダ
(推奨する運用)。
マニフェスト内の実行権限による書き込み権限 なし 環境変数 %TEMP%が示すフォルダ。
マニフェスト なし Users権限の書き込み権限 あり ユーザプログラムの作業フォルダ
(推奨する運用)。
Users権限の書き込み権限 なし 作業フォルダが環境変数 %ProgramFiles% あるいは、%WinDir%が示すフォルダ配下の場合は、仮想ストア(%LocalAppData%\VirtualStore)の該当するフォルダ。
それ以外の場合は、環境変数 %TEMP%が示すフォルダ。

Object Broker C++のトレース

通信に関する詳細な調査の際は、Object Broker C++のトレースログが必要になります。 Object Broker C++の詳細トレースを採取するには、次のレジストリ内容を適用してください(値がない場合は作成してください)。

レジストリキー HKEY_LOCAL_MACHINE\SOFTWARE\NEC\ObjectSpinner\1
名 前 種 類 値(既定値)
LoggingLevel 文字列
(REG_SZ)
INFORMATION (既定値: ERROR)
MessagingLog 文字列
(REG_SZ)
on (既定値: off)
MessageBodyLog 文字列
(REG_SZ)
on (既定値: off)

出力されるトレースファイル名は <インストールディレクトリ>\ObjectBroker\log配下のmessage.logObLog.logになります。

ファイルサイズの上限やファイル名を変更する場合は、次のレジストリ内容を適用してください(値がない場合は作成してください)。

レジストリキー HKEY_LOCAL_MACHINE\SOFTWARE\NEC\ObjectSpinner\1
名 前 種 類 値(既定値)
LogLimit 文字列
(REG_SZ)
ログファイルサイズの上限(既定値: 10240Kバイト, 値がない場合は無制限)
ファイルサイズの上限をKバイト単位で設定します。この上限を超えると、ファイル名の末尾に「_old」を付加してバックアップし、新しいログファイルを作成します。
LoggingOutput 文字列
(REG_SZ)
ロギングファイル名(既定値: <インストールディレクトリ>\ObjectBroker\log配下のObLog.log
MessageLogFile 文字列
(REG_SZ)
通信ログファイル名(既定値: <インストールディレクトリ>\ObjectBroker\log配下のmessage.log
IFコンパイラのトレース

IFコンパイラはIFコンパイル時にランタイムエラーなどの例外が発生した場合、作業フォルダ(カレントディレクトリ)内に woifgen.logを出力します。