Powered by SmartDoc

Stateless Session Bean

Stateless Session Bean

Session Beansは、クライアントが必要に応じて呼び出す処理をまとめたものです。クライアントの特定のセッションに対応しており、セッション開始と同時に生成され、セッション終了時に消滅します。

Session Beansにも、2つの種類があります。

ひとつめは、"Stateless Session Beans"です。Stateless Session Beansは、インスタンスに固有のフィールドがないため内部状態を持たず、ユーティリティクラスのように振る舞うEJBです。

ふたつめは、"Stateful Session Beans"です。こちらは内部状態を持っています。

ここでは、Stateless Session Beanについて解説しましょう。

サンプルアプリケーション

本章では、Helloサンプルアプリケーションを作成します。ファイルの構成は次のとおりです。

インタフェース

まずは、Stateless Session Beansが公開するメソッドを定義しているインタフェースである"Hello.java"です。従来のEJBでは、EJBオブジェクトインタフェースを継承する必要がありましたが、EJB 3.0では、POJI + Annotationのスタイルとなっています。

Hello.java
import javax.ejb.Remote;

@Remote
public interface Hello {
	public String sayHello(String name);
}

このインタフェースが、Remote (=別のマシン)で実行される可能性があるとします。この場合、インタフェースに@Remoteアノテーションを付加することで、このEJBの機能を別のマシンから呼びだすことができるようになります。具体的には、RMI/IIOPが用いられます。

@Remote public interface Hello {…}

同一のJava Virtual Machineからしか動かさない場合、@Localアノテーションを付加します。

@Local public interface Hello {…}

何もアノテーションを付けなかった場合、@Localを付けるのと同じことになります。

public interface Hello {…}

Stateless Session Bean の作成

次は、Stateless Session Beanの本体です。先ほど作成したインタフェースを実装しています。

HelloImpl.java
import javax.ejb.Stateless;

@Stateless
public class HelloImpl implements Hello {
	public String sayHello(String name) {
		return "Hello, " + name + "!";
	}
}

Stateless Session Beanであることを示すために、@Statelessアノテーションを付加しています。

従来のEJBでは、SessionBeanインタフェースを実装したり、ejbCreate, ejbRemoveメソッドなどを用意する必要がありました。EJB 3.0では、Helloインタフェースを実装したPOJOになっています。

クライアントプログラム (1) JNDIの利用

続いて、クライアントプログラムです。クライアントプログラムでは、Helloインタフェースを呼び出す必要があります。どうやればよいのでしょうか。

HelloClient.java
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.ejb.EJB;

public class HelloClient {
	private static Hello hello;
	public static void main(String[] args) {
		try {
			Context context = new InitialContext();
			hello = (Hello)context.lookup("Hello");
			String message = hello.sayHello(args[0]);
			System.out.println(message);
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}
}

このプログラムでは"JNDI"を使っています。"JNDI"は、Javaでディレクトリサービス(LDAPなど)にアクセスするためのAPIです。抽象的な「名前」をキーにしてオブジェクトを取得できます。JNDIはJDBC, EJB, JavaMailといった技術でよく利用されています。

ソースコードのうち、JNDIにアクセスする部分を抜き出してみましょう。

// Contextを取得
Context context = new InitialContext();
// 名前に対応する Hello を取得
hello = (Hello)context.lookup("Hello");

まず、InitialContextを取得しています。InitialContextとは、JNDIで検索をするときの出発点です。ファイルシステムに例えると、ルートディレクトリに相当します。Contextは、ディレクトリに相当します。

次に、Contextのlookupというメソッドを使い、"Hello"という名前からHello型のインスタンスを取得しています。

GlassFishでは次のコマンドを使って、どのような名前が有効になっているか調べることができます。

asadmin list-jndi-entries

サンプルアプリケーションの実行 (1)

では、今回のサンプルアプリケーションをGlassFishで動かすための手順をご紹介しましょう。

環境変数の設定

"JAVAEE_HOME"という環境変数を設定して、その値にGlassFishをインストールしたディレクトリを指定します。

そして、%JAVAEE_HOME%\binにPATHを通します。

GlassFishの起動

GlassFishを起動します。

asadmin start-domain

サンプルアプリケーションのコンパイル

サンプルアプリケーションをコンパイルします(Windowsで実行した例)。

cd hello-jndi
javac -classpath %JAVAEE_HOME%\lib\javaee.jar *.java

Jarファイルの作成と配備 (デプロイ)

Jarファイルを生成します。

jar cvf hello.jar Hello.class HelloImpl.class

そして、生成したJarファイルをGlassFishのコンテナ上に置きます。このことを「配備」あるいは「デプロイ」と呼びます。

copy hello.jar %JAVAEE_HOME%\domains\domain1\autodeploy

クライアントプログラムの実行

クライアントプログラムを実行します。

java -classpath %JAVAEE_HOME%\lib/javaee.jar; (つなげて入力)
%JAVAEE_HOME%\lib\appserv-rt.jar;. HelloClient tomoharu

クライアントプログラム (2) Dependency Injection

クライアントプログラムについて、もう少し考えてみましょう。

JNDIを使ったクライアントプログラムでは、「名前」をプログラムに直接記述することで、Helloオブジェクトを取得していました。

この「名前」は、コンテナ環境に依存しています。

このことを、Dependency Injectionを使って解決してみましょう。

HelloClient.java
import javax.ejb.EJB;

public class HelloClient {
	@EJB static Hello hello;
	public static void main(String[] args) {
		String message = hello.sayHello(args[0]);
		System.out.println(message);
	}
}

ここでは、helloフィールドに、"@EJB"というAnnotationが付加されています。このAnnotationは、該当するEJBを注入するためのものです。このことにより、コンテナ固有の情報がソースコードに表れなくなりました。

このプログラムでは、Dependency Injectionを用いるため、実行するには「クライアントコンテナ」というソフトウェアが必要になります。

サンプルアプリケーションの実行 (2)

クライアントプログラムの実行

Dependency Injectionを使ったクライアントプログラムの場合、appclientコマンドを使用する必要があります。

appclientコマンドは、クライアントコンテナを起動してアプリケーションを実行するためのコマンドです。このコマンドによって、@EJBへの依存性注入が行われます。

appclient HelloClient tomoharu