- 追加された行はこの色です。
- 削除された行はこの色です。
// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
J2EEコンテナであるJBossを使ってEJBの勉強をしてみました。以下、作業メモです。
***EJBの使い方 [#l6778de5]
例えば、sayHello()メソッドでStringを返却するEJBを作る場合以下の物が必要です。
-sayHello()メソッドをインタフェースに持つ、Helloインターフェース(extends EJBObject)
-実際にビジネスロジック((っつってもHello EJBってかえすだけ))を記述する、HelloBean(implements SessionBean)
-HelloインタフェースをCreateするメソッドを持つ、HelloHome インタフェース(extends EJBHome)
これとさまざまなDD(Deployment Descriptor)ファイルを作成し、サーバにデプロイしておくことで、ビジネスロジックを使用したいヒト(プログラム)は、
-JNDI経由で、Homeインタフェースの取得
-Homeインタフェースから、実際のビジネスロジックをcreate
-createしたビジネスロジックを実行
という手順となります。
このようにすることによって、ビジネスロジックがどこで実行されたかを気にしないで結果を得ることができるようになります。つまり可用性が向上するわけですね。
***まずはJNDI名と、EJBたちの関係 [#u1713768]
さて、先ほどJNDI経由でHomeインタフェースを取得すると言いましたが、EJBではオブジェクトを取得する際、必ずInitialContextを経由します。この機構をJNDIといいます。
InitialContextはあらかじめ、Stringのキー値とオブジェクトを対にしてコンテナに登録しておき、そのキー値でオブジェクトを検索し取得するのですが、そのキー値とオブジェクトの関係を理解しないと相当ややこしいです。
先の例で行くと、
initContext = new InitialContext();
Object ref = initContext.lookup("HelloEJBHoge");
HelloHome home = (HelloHome) PortableRemoteObject.narrow(ref,HelloHome.class);
とルックアップするのですが、この"HelloEJBHoge"がキー値で、HelloHome が登録されているオブジェクトです。
話を整理すると、
-コンテナには、HelloEJBHogeというキーで、hello.HelloHomeオブジェクトが登録されている。
-InitialContextをそのキー値でlookupすることで、hello.HelloHomeオブジェクトを取得する
ということですが、当然のように
-そもそもコンテナにどうやってオブジェクトを登録するのか?
という疑問がわき起こります。もっと具体的にいうと
-InitialContextをlookupする際のキー"HelloEJBHoge"と、hello.HelloHomeオブジェクトはどこで関連づけられるのでしょうか??
ということです。
***考察 [#p0b2925c]
さて先の疑問を解決したいと思います。まだTry and Errorです。。。
まず、hello.HelloHomeに名前を付けます。これはJ2EEの仕様内であるejb-jar.xmlによって行われます。
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>HelloEJB</ejb-name>
<home>hello.HelloHome</home> <-ココ
<remote>hello.Hello</remote>
<ejb-class>hello.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
これで、hello.HelloHomeにはHelloEJBという''EJB名''が付けられました。
さらに、このEJB名"HelloEJB"とコンテナ側に登録されている"HelloEJBHoge"は、JBoss独自ファイルである、jboss.xmlで関連づけられます。((WebSphereにはWebSphereの独自ファイルがあります))
<?xml version="1.0"?>
<jboss>
<enterprise-beans>
<session>
<ejb-name>HelloEJB</ejb-name>
<jndi-name>HelloEJBHoge</jndi-name>
</session>
</enterprise-beans>
</jboss>
これでHelloEJBHogeというキーとhello.HelloHomeが関連づけられました。HelloEJBHogeでlookupすればhello.HelloHomeを取得できそうです。実際にやってみると
public static void main(String[] args) throws NamingException,
RemoteException, CreateException {
InitialContext initContext = null;
try {
initContext = new InitialContext();
Object ref = initContext.lookup("HelloEJBHoge");
HelloHome home = (HelloHome) PortableRemoteObject.narrow(ref,
HelloHome.class);
Hello hello = home.create();
System.out.println(hello.sayHello());
} finally {
if (initContext != null) {
initContext.close();
}
}
}
これで確かに稼動しました!。((Eclipseでやったときは、実行時のクラスパスに${JBOSS_HOME}/client内のJarにパスを通さないとダメかも。。))
***クライアントからではなく、サーブレットなどからアクセスする [#b6921602]
context.lookup("java:comp/env/ejb/HelloEJB");
これでweb.xml内のejb-refを ejb/HelloEJB で検索します。
<ejb-ref>
<ejb-ref-name>ejb/HelloEJB</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>hello.HelloHome</home>
<remote>hello.Hello</remote>
<ejb-link>HelloEJB</ejb-link>
</ejb-ref>
----
この記事は
#vote(おもしろかった,そうでもない)
#comment
#topicpath
SIZE(10){現在のアクセス:&counter;}