![]() |
![]() |
|
|
| |
プログラミング
WebLogic jCOM は、Windows DCOM ネットワーク プロトコルを使用してローカルおよびリモート COM コンポーネントと pure Java 環境間の通信を実現します。以下の節では、WebLogic jCOM を使用して COM クライアントから Java コンポーネントにアクセスするためにプログラマが行う必要があることについて説明します。
サーバサイドのプログラミング要件
サーバ サイドのプログラミング要件は、ほとんどのプログラミング モデルの場合、コンフィグレーションとブリッジのコンパイルおよびアクティブ化に限られます。アーリー バインド プログラミング モデルまたはレイト バインド カプセル化プログラミング モデルを実装する場合、ラッパーと型ライブラリも生成する必要があります。
ブリッジ ファイルの JCOMBridge.java
は、WebLogic jCOM に用意されています。このファイルは前述のすべての例で使用されており、独自のブリッジ ファイルを作成するための土台としても使用できます。
ブリッジをサーバ サイドに構築するには、実装するプログラミング モデルに関係なく、以下のことを行う必要があります。
setEnv
ファイルを実行する)。
env.put(Context.PROVIDER_URL, "t3://localhost:7001")
build.xml
を実行して、WebLogic jCOM ブリッジ ファイルをコンパイルします。そのためには、次のコマンドを実行します。
ant
JCOMBridge.java
を実行する次の文を使用して、サーバ サイドのブリッジを起動します。
java -classpath %CLASSPATH% -DJCOM_DCOM_PORT=7050 JCOMBridge
ここで 7050
は、WebLogic jCOM ブリッジがクライアントとサーバ間の通信をリスンする必要があるポートです。
ブリッジ ファイル、JCOMBridge.java
は、WLS TCP/IP アドレスとリスン ポートを定義し、JVM 名を JNDI に登録します。
アーリー バインディングまたはレイト バインド カプセル化を実装する場合は、さらに次の手順を行う必要があります。
java2com
ツールを使用して、Java コンポーネントの Java ラッパーと IDL ファイルを生成します。
java com.bea.java2com.Main
この行を実行すると、java2com ウィンドウが開きます。[Java Classes & Interfaces] フィールドに、使用するクラス(ブリッジ クラスを含む)の名前を入力する必要があります。
javac
Output Directory
\*.java
クライアント サイドのプログラミング要件
クライアント システムで必要なプログラミング手順については、以下のプログラミング モデルを実装する方法を見ていきます。
DCOM ゼロ クライアント プログラミング モデル
DCOM ゼロ クライアント プログラミング モデルの実装に必要な基本的なクライアント サイト プログラミング手順は次のとおりです(VB クライアントが WebLogic Server 上の EJB にアクセスする場合)。
com.bea.jcom.GetJvmMoniker
を使用して、ブリッジの場所のコード化された参照(objref)を生成します。パラメータとして、サーバ マシンのフルネームまたは TCP/IP アドレス、およびブリッジにアクセスできるポートを指定します。次に例を示します。
java com.bea.jcom.GetJvmMoniker mymachine.mycompany.com 7050
または
java com.bea.jcom.GetJvmMoniker localhost 7050
Set objBridge = GetObject("objref:
generatedobjref
")
Set
objHome = objBridge.get("JVMName
:jndi name of ejb
")
DCOM レイト バインド プログラミング モデル
DCOM レイト バインド プログラミング モデルの実装に必要な基本的なクライアント サイト プログラミング手順は次のとおりです(VB クライアントが WebLogic Server 上の EJB にアクセスする場合)。
objHome
の COM バージョンの宣言に注意してください。COM オブジェクトは、サーバ サイドにある EJB のホーム インタフェースのインスタンスにリンクされます。
Dim objHome As Object
Private Sub Form_Load()
'Handle errors
On Error GoTo ErrOut
'Bind the EJB's HomeInterface object via JNDI
Set objHome = GetObject("
JVMName
:jndi name of ejb
")
GetObject
は、WebLogic Server 上の JNDI ルックアップを通してオブジェクトを取得します。JVM(「JVMName
」)は、手順 3. の説明のとおりレジストリに登録する必要があります。
regjvm
ツールを使用してローカル Java 仮想マシンを登録します。そのためには、そのマシン名を Windows レジストリに追加し、TCP/IP アドレスと、WebLogic jCOM が WebLogic jCOM 要求をリスンするクライアントとサーバ間の通信ポートに関連付けます。次に例を示します。
regjvmcmd
JVMName
localhost[7050]
DCOM アーリー バインド プログラミング モデル
DCOM アーリー バインド プログラミング モデルの実装に必要な基本的なクライアント サイト プログラミング手順は次のとおりです(VB クライアントが WebLogic Server 上の EJB にアクセスする場合)。
midl
generatedIDLFileName
.idl
コンパイルの結果、名前が同じで拡張子が .tlb
の型ライブラリが生成されます。
regtlb /unregisterall
regtlb
generatedIDLFileName
.tlbJVMName
上の最初の行は、登録済みの型ライブラリ バージョンの登録を解除するために regtlb.exe
を呼び出します。2 番目の行は、新しくコンパイルされた型ライブラリを登録し、その型ライブラリにリンクされる JVM の名前("JVMName
")を指定します。WebLogic jCOM ランタイムでは、型ライブラリで定義されたオブジェクト呼び出しを適切なラッパー クラスにリンクするためにこの情報が必要となります。
Dim objCOM As
generatedIDLFileName
.generated class name
たとえば、完全修飾 Java クラスが examples
.ejb.basic
.containerManaged
.AccountHome
の場合、生成されるクラス名は ExampleEjbBasicContainerManagedAccountHome
となります。
Dim objTemp As Object
Dim objBridge As New
generatedIDLFileName
.COMtoWebLogic
Set objTemp = GetObject("
JVMName
:jndi name of ejb
")
Set objHome = objBridge.narrow(objTemp,"
fully qualified java class
")
objTemp
オブジェクトはレイト バインド モデルを使用して EJB オブジェクトの参照を取得することに注意してください。レイト バインド オブジェクトはブリッジの「narrow」メソッドに受け渡され、次にアーリー バインド オブジェクトが与えられます。
regjvm
ツールを使用してローカル Java 仮想マシンを登録します。そのためには、そのマシン名を Windows レジストリに追加し、TCP/IP アドレスと、WebLogic jCOM が WebLogic jCOM 要求をリスンするクライアントとサーバ間の通信ポートに関連付けます。
regjvmcmd
JVMName localhost
[7050]
DCOM レイト バインド カプセル化プログラミング モデル
レイト バインド カプセル化を使用すると、アーリー バインド プログラミングの主要なメリットはそのままに、ラッパーと型ライブラリを必要としない柔軟なレイト バインド モデルを実装できます。
たとえば、Visual Basic クライアントが EJB にアクセスする場合は、次のことを行う必要があります。
midl
generatedIDLFileName
.idl
コンパイルの結果、名前が同じで拡張子が .tlb
の型ライブラリが生成されます。
regtlb /unregisterall
regtlb
generatedIDLFileName
.tlbJVMName
上の最初の行は、登録済みの型ライブラリ バージョンの登録を解除するために regtlb.exe
を呼び出します。2 番目の行は、新しくコンパイルされた型ライブラリを登録し、その型ライブラリにリンクされる JVM の名前("JVMName
")を指定します。WebLogic jCOM ランタイムでは、型ライブラリで定義されたオブジェクト呼び出しを適切なラッパー クラスにリンクするためにこの情報が必要となります。
Class_Initialize
メソッドを追加し、このメソッドの中に、モジュール レベル オブジェクト変数に EJB の参照を割り当てるために必要なソース コードを挿入します。必要な初期化ソースについては、「
DCOM レイト バインド プログラミング モデル」を参照してください。
Implements
キーワードを使用して、アクセスする必要があるオブジェクトの参照を実装します。EJB オブジェクトを参照するには、型ライブラリの名前の後にドットを付けます(Implements
generatedIDLFileName
.
generated class name
)。
たとえば、完全修飾 Java クラスが examples.ejb.basic.containerManaged.AccountHome
の場合、generated class name
は ExampleEjbBasicContainerManagedAccountHome
となります。
これが済んだら、作成したクラスをインスタンス化し、あたかもアーリー バインドであるかのようにすべての EJB 機能にアクセスできます。VP クライアント ソースに採用されたメソッドとプロパティのインタフェースが静的である限り、EJB に対するどのような変更も VB プロジェクトに影響を与えません。
ネイティブ モード プログラミング モデル
ネイティブ モードでは、COM クライアントはクライアントと同じマシン上で動作している Java オブジェクトにアクセスします。WebLogic jCOM は、ネイティブ コードを使用してこの対話を容易にします。ネイティブ モードの詳細については、『WebLogic jCOM リファレンス』の「ネイティブ モード」を参照してください。
Java オブジェクトのインスタンス化のインターセプト
Java オブジェクトのインスタンス化を制御する場合、com.bea.jcom.Instanciator
インタフェースを実装するクラスを作成します。このインタフェースは、次のような 1 つのメソッドを持ちます。
public Object instanciate(String javaClass) throws com.bea.jcom.AutomationException;
Jvm.register(...) を呼び出すときに参照を 2 番目のパラメータとしてインスタンシエータに渡します。
com.bea.jcom.Jvm.register("MyJvm", myInstanciator);
WebLogic jCOM によって使用されるデフォルトのインスタンシエータは次のとおりです。
public final class DefaultInstanciator implements com.bea.jcom.Instanciator {
public Object instanciate(String javaClass)
throws com.bea.jcom.AutomationException {
try {
return Class.forName(javaClass).newInstance();
} catch(Exception e) {
e.printStackTrace();
throw new AutomationException(e);
}
}
}
たとえば、これは VB と EJB のブリッジです(Sun の JNDI Tutorial を基礎にしている)。
import javax.naming.*;
import java.util.Hashtable;
import com.bea.jcom.*;
public class VBtoEJB {
public static void main(String[] args) throws Exception {
Jvm.register("ejb", new EjbInstanciator());
Thread.sleep(10000000);
}
}
class EjbInstanciator implements Instanciator {
Context ctx;
EjbInstanciator() throws NamingException {
Hashtable env = new Hashtable(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://... TBS ...
");
ctx = new InitialContext(env);
}
public Object instanciate(String javaClass) throws AutomationException {
try {
try {
return Class.forName(javaClass).newInstance();
} catch(Exception e) {}
return ctx.lookup(javaClass);
} catch (Throwable t) {
t.printStackTrace();
throw new AutomationException(new Exception("Unexpected: " + t)); }
}
}
上のコードをコンパイルしたら、次のようにそれをマシン(development.company.com
)上で実行します。
java -DJCOM_DCOM_PORT=4321 VBtoEJB
次に、Windows マシン上で次のように WebLogic jCOM regjvmcmd
コマンドを使用します。
regjvmcmd ejb development.company.com[4321]
次に、VB から以下を使用します。
Set myEjb = GetObject("ejb:cn=ObjectName")
MsgBox myEjb.someProperty
myEjb.myMethod "a parameter"
コンストラクタを使用した COM からの Java オブジェクトのインスタンス化
COM にはコンストラクタの概念はありません。1 つの方法は、デフォルト コンストラクタを定義して、適切なパラメータを取る静的メンバーを定義し、オブジェクトをインスタンス化して返すことです。
public class MyClass {
public MyClass() {}
public MyClass(String p1, int p2, double p3) {
...
}
public static MyClass createMyClass(String p1, int p2, double p3) {
return new MyClass(p1, p2, p3);
}
}
もう 1 つの方法は、WebLogic jCOM のインスタンス化インターセプト機能を使用することです。JVM を登録するときに、オブジェクトの参照を受け渡すことができます。このオブジェクトのクラスは、GetObject
("MyJvm:MyClass"
) を使用するときに呼び出される特別な Java jCOM インタフェースを実装します。コロンの後はすべて渡すので、実際には GetObject
("MyJvm:MyClass
(1, 2, three, 4.0"
) を行って、インターセプタで渡される文字列を解析し、適切なコンストラクタを呼び出します。
シングルトン Java オブジェクトの実装
COM 用語では、オブジェクトのインスタンスが常に 1 つだけ存在する場合、そのオブジェクトはシングルトンです。CreateInstance を呼び出すたびに、同じオブジェクトの参照を取得します。このため、すべてのクライアントが同じインスタンスにアクセスすることが保証されます。
Java オブジェクトのインスタンス化を制御することで、COM クライアントからアクセスできるシングルトン Java オブジェクトを実装できます。次に、mySingletonClass
というクラスのイニシエータの例を示します。
import java.util.*;
import com.bea.jcom.*;
public class COMtoJava {
public static void main(String[] args) throws Exception {
try {
Jvm.register("MyJvmId", new SingletonInstanciator("MySingletonClass"));
while (true) { // 永遠に待機
Thread.sleep(100000);
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
class SingletonInstanciator implements Instanciator {
String singletonClassname;
static Object singletonObject = null;
SingletonInstanciator(String singletonClassname) {
try {
this.singletonClassname = singletonClassname;
if (singletonObject == null) {
System.out.println("SingletonInstanciator: creating the singleton [" + singletonClassname + "]");
// シングルトンを初期化
Class classObject = Class.forName(singletonClassname);
singletonObject = classObject.newInstance();
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public Object instanciate(String javaClass) throws AutomationException {
try {
System.out.println("instanciate for " + javaClass);
// 要求がシングルトンの作成の場合、既存のインスタンスを返す
if (javaClass.equals(singletonClassname)) {
return singletonObject;
} else {
Class classObject = Class.forName(javaClass);
return classObject.newInstance();
}
}
catch (Exception e)
{
System.out.println("Failed to instanciate class " + javaClass);
System.out.println(e.getMessage());
e.printStackTrace();
System.out.println("Throwing exception back to caller.");
throw new AutomationException(e);
}
}
}
MySingletonClass
実装のサンプルを以下に示します。
public class MySingletonClass {
public MySingletonClass() {
System.out.println("MySingletonClass constructor called.");
}
public int Method1(int val) {
return val + 1;
}
}
上の両方をコンパイルしたら、次のように COMtoJava をマシン(development.company.com)上で実行します。
java -DJCOM_DCOM_PORT=4321 COMtoJava
次に、Windows マシン上で次のように WebLogic jCOM regjvmcmd
コマンドを使用します。
regjvmcmd MyJvmId development.company.com[4321]
次に、VB から以下を使用します。
Set objMySingleton1 = GetObject("MyJvmId:mySingletonClass")
Set objMySingleton2 = GetObject("MyJvmId:mySingletonClass")
MsgBox objMySingleton1 & objMySingleton2
これにより、同じオブジェクトの 2 つの参照が作成されます。
![]() |
![]() |
![]() |