Shammer's Philosophy

My private adversaria

HelloWorld, EJB 3.0(StatelessSessionBean)

WLS付属のEJB3.0のサンプルは、複雑すぎる・・・一応、構成図もついているが、サンプルなんてHelloWorldレベルのものでいいと思う。と、言う訳で自分で書いた。どうもテストケースとかの管理が下手なので、いつでもアクセスできるようにここに書いておく事にした。
まずは、Hello.java

import javax.ejb.Remote;

@Remote
public interface Hello 
{
     public void sayHello();
}

Hello.javaをimplementsしたEJB3.0の実体(HelloBean.java)。

import javax.ejb.Remote;
import javax.ejb.Stateless;

@Remote
    @Stateless(mappedName="HelloWorld")
    public class HelloBean implements Hello 
 {
     public void sayHello()
     {
	 System.out.println("Hello, EJB 3.0.");
     }
}

HelloBean.javaを呼び出すスタンドアロンクライアント(HelloClient.java)。

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;

public class HelloClient 
{
    private static final String WL_INITIAL_CONTEXT_FACTORY = "weblogic.jndi.WLInitialContextFactory";
    private static final String HELLO_BEAN_JNDI_VALUE = "HelloWorld#Hello";

    public static void main(String[]args)throws Exception
    {
	if( args.length != 1 ){
	    System.out.println("Usage: java HelloClient <WLS_URL>");
	    System.exit(1);
	}
	
	Hashtable<String,String> h = new Hashtable<String,String>();
	h.put(Context.INITIAL_CONTEXT_FACTORY, WL_INITIAL_CONTEXT_FACTORY);
	h.put(Context.PROVIDER_URL, args[0]);
	h.put(Context.SECURITY_PRINCIPAL, "weblogic");
	h.put(Context.SECURITY_CREDENTIALS, "welcome1");
	Context context = new InitialContext(h);

	Hello bean = (Hello)context.lookup(HELLO_BEAN_JNDI_VALUE);
	bean.sayHello();
    }
}

当然だが、環境に依存するユーザーやパスワードの情報は書き換えが必要。
そして、build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="Ejb_HelloWorld" basedir="." default="buildEar">

  <property name="BEA_HOME" value="/Oracle/Middleware/server1034"/>
  <property name="WLS_HOME" value="${BEA_HOME}/wlserver_10.3"/>
  <property name="jarname" value="EJB30-HelloWorld" />

  <property name="appname" value="HelloWorld" />

  <property name="src"         value="${basedir}/src"/>
  <property name="build"       value="${basedir}/build"/>
  <property name="dist"        value="${basedir}/dist"/>
  <property name="lib"        value="${basedir}/lib" />

  <property name="src.server"         value="${src}/server"/>
  <property name="src.client"         value="${src}/client"/>
  <property name="build.server"       value="${build}/server"/>
  <property name="build.client"       value="${build}/client"/>
  <property name="dist.server"        value="${dist}/server"/>
  <property name="dist.client"        value="${dist}/client"/>
  
  <path id="dependencies">
    <pathelement location="${WLS_HOME}/server/lib/weblogic.jar"/>
  </path>

  <target name="clean">
    <echo>Cleaning the directory</echo>
    <delete dir="${build}" />
    <delete dir="${dist}" />
  </target>

  <target name="compile" depends="clean">
    <echo>Compiling EJB</echo>
    <echo message="BEA_HOME: ${BEA_HOME}"/>
    <echo message="WLS_HOME: ${WLS_HOME}"/>
    <mkdir dir="${build}/server/classes"/>
    <javac srcdir="${src.server}" destdir="${build}/server/classes" debug="on" >
      <classpath refid="dependencies"/>
    </javac>
  </target>

  <target name="compileClient">
    <echo>Compiling Client class</echo>
    <mkdir dir="${build.client}/classes"/>
    <javac srcdir="${src.client}" destdir="${build.client}/classes" debug="on" >
      <classpath refid="dependencies"/>
      <classpath location="${build.server}/classes" />
    </javac>
  </target>

  <target name ="buildEar" depends="compile">
    <echo>Building EJB EAR</echo>
    <mkdir dir="${dist.server}"/>
    <jar jarfile ="${dist.server}/${jarname}.jar" basedir="${build}/server/classes"/>
    <jar jarfile ="${dist.server}/${appname}.ear"  basedir="${dist.server}" />
  </target>

  <target name="run" depends="compileClient">
    <echo>Executing client class</echo>
    <java classname="HelloClient" fork="yes">
      <arg line="t3://localhost:7001"/>
      <classpath>
	<pathelement location="${build.client}/classes"/>
	<pathelement location="${dist.server}/EJB30-HelloWorld.jar"/>
	<pathelement location="${lib}/wlfullclient.jar"/>
      </classpath>
    </java>
  </target>

</project>

よくわからなかったのは、HelloBean.javaで@Stateless(mappedName="HelloWorld")としたら、実際にJNDIでバインドされる変数はHelloWorld#Helloになったこと。これはWLS独自の動作なのだろうか。nameにすると、また違った動作になるのかもしれない。
JavaDocには下記のようにあるだけだ。

A product specific name(e.g. global JNDI name) that this session bean should be mapped to. Application servers are not required to support any particular form or type of mapped name, nor the ability to use mapped names. The mapped name is product-dependent and often installation-dependent. No use of a mapped name is portable. 

あと、スタンドアロンのJavaClientで必要になるクラスライブラリをまとめて作成することが可能なようだ。手順はこのドキュメントにある。
WLS_HOME/server/libへ行き、java -jar wljarbuilder.jarというコマンドを実行すると、wlfullclient.jarというファイルができる。これをクライアントのCLASSPATHへ追加すればOK。


このサイトを参考にしました。