2014年1月2日木曜日

jboss7.1.1 で EJB をJSP,SERVLET,CLIENTから呼び出す。

せっかく、JBoss7.1.1 をインストールしたので、EJBを試してみる。EJBの利点の一つに作成したモジュールの再利用性にあるらしい。WEB用に作ったEJBモジュールをクライアントプログラムからも呼び出し確認してみる。

JBoss7.1.1 で EJB !


(1) ディレクトリ構成
$ tree .
.
├── ejbclient
│   ├── ejbclient.class
│   ├── ejbtest
│   │   └── Greeting.class
│   └── testrun.sh
├── ejbtest
│   ├── WEB-INF
│   │   └── classes
│   │       ├── Srvtest01.class
│   │       └── ejbtest
│   │           ├── Greeting.class
│   │           └── GreetingBean.class
│   └── test01.jsp
├── srcclient
│   ├── Greeting.java
│   ├── build.xml
│   └── ejbclient.java
└── srcejb
    ├── Greeting.java
    ├── GreetingBean.java
    ├── Srvtest01.java
    └── build.xml

8 directories, 14 files

(1) EJB モジュール

・Greeting インタフェース
package ejbtest;

import javax.ejb.Remote;

@Remote
public interface Greeting {
   public String SayHello();
}

・GreetingBean
package ejbtest;

import javax.ejb.Stateless;

@Stateless
public class GreetingBean implements Greeting {

   public GreetingBean() {
   }

   public String SayHello() {
      return("Hello EJB World!");
   }
}

(2) EJBテスト用サーブレットと build.xml

・テスト用サーブレット
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
import javax.ejb.EJB;
import ejbtest.Greeting;

@WebServlet(name="Srvtest01", urlPatterns={"/Srvtest01"})
public class Srvtest01 extends HttpServlet {
  @EJB
  private Greeting greeting;

  @Override
  public void doGet(HttpServletRequest req,
                    HttpServletResponse res) throws ServletException,IOException {

    res.setContentType("text/html; charset=UTF-8");
    PrintWriter out = res.getWriter();

    out.println("");
    out.println("");
    out.println(greeting.SayHello());
    out.println("");
    out.println("");

    out.close();
  }
}

・build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="ejbtest" default="main" basedir=".">

   <property name="build.classes" location="../ejbtest/WEB-INF/classes" />
   <property name="jboss" location="/home/ユーザ/jboss7/modules" />
   <target name="main" depends="compile" />

   <target name="compile">
      <mkdir dir="${build.classes}" />
      <javac destdir="${build.classes}" srcdir=".">
        <classpath>
          <pathelement path="${jboss}/javax/servlet/api/main/jboss-servlet-api_3.0_spec-1.0.0.Final.jar" />
          <pathelement path="${jboss}/javax/transaction/api/main/jboss-transaction-api_1.1_spec-1.0.0.Final.jar" />
          <pathelement path="${jboss}/javax/ejb/api/main/jboss-ejb-api_3.1_spec-1.0.1.Final.jar" />
          <pathelement path="${jboss}/javax/inject/api/main/javax.inject-1.jar" />
        </classpath>
      </javac>
   </target>
</project>

(3) EJB パッケージを配備して動作確認
$ cd srcejb
$ ant
$ cd ../ejbtest
$ jar cvf ../ejbtest.war .
$ cp ../ejbtest.war ~/jboss7/standalone/deployments

(4) JSP からEJBの呼び出し

JSP は@EJBアノテーションは使えないので、jndi名のlookupとする。
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context,javax.naming.InitialContext"%>
<%@ page import="ejbtest.Greeting"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSPテスト</title>
</head>

<body>
<%
   Context ctx=new InitialContext();
   Greeting greeting =
      (Greeting) ctx.lookup("java:app/ejbtest/GreetingBean!ejbtest.Greeting");

   out.println(greeting.SayHello());
%>
</body>
</html>

・再配備と実行
$ cd ejbtest
$ jar cvf ../ejbtest.war .
$ rm -rf ~/jboss7/standalone/deployments/ejbtest.*
$ cp ../ejbtest.war ~/jboss7/standalone/deployments

(5) client よりEJBの呼び出し

jndi名がなぜ、JSPの場合(java:global/ejbtest/GreetingBean!ejbtest.Greeting)で、クライント呼び出しの場合(ejbtest/GreetingBean!ejbtest.Greeting)と java:global/ を付けるとうまくいかないのか謎のままである。
・クライアントソース
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import ejbtest.Greeting;

public class ejbclient {

  public static void main(String[] args) {
    try {
      InitialContext initialContext = getInitialContext();

      Greeting greeting =
      (Greeting) initialContext.lookup("ejbtest/GreetingBean!ejbtest.Greeting");

      System.out.println(greeting.SayHello());

    } catch (NamingException e) {
      e.printStackTrace();
    }
  }

  private static InitialContext getInitialContext() throws NamingException{

    Properties properties = new Properties();

    properties.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");
    properties.put(Context.PROVIDER_URL, "remote://localhost:4447");
    properties.put("jboss.naming.client.ejb.context", true);
    properties.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
    properties.put(Context.SECURITY_PRINCIPAL, "testuser");
    properties.put(Context.SECURITY_CREDENTIALS, "testpassword");

    return new javax.naming.InitialContext(properties);
  }
}

・build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="ejbtest" default="main" basedir=".">

   <property name="jboss" location="/home/ユーザ/jboss7/modules" />
   <target name="main" depends="compile" />

   <target name="compile">
      <javac destdir="../ejbclient" srcdir=".">
        <classpath>
          <pathelement path="${jboss}/javax/servlet/api/main/jboss-servlet-api_3.0_spec-1.0.0.Final.jar" />
          <pathelement path="${jboss}/javax/transaction/api/main/jboss-transaction-api_1.1_spec-1.0.0.Final.jar" />
          <pathelement path="${jboss}/javax/ejb/api/main/jboss-ejb-api_3.1_spec-1.0.1.Final.jar" />
          <pathelement path="${jboss}/javax/inject/api/main/javax.inject-1.jar" />
        </classpath>
      </javac>
   </target>
</project>

・テストユーザを作成
$ ./add-user.sh

What type of user do you wish to add? 
 a) Management User (mgmt-users.properties) 
 b) Application User (application-users.properties)
(a): b

Enter the details of the new user to add.
Realm (ApplicationRealm) : 
Username : testuser
Password : 
Re-enter Password : 
What roles do you want this user to belong to? (Please enter a comma separated list, or leave blank for none) : 
About to add user 'testuser' for realm 'ApplicationRealm'
Is this correct yes/no? yes
Added user 'testuser' to file '/home/ユーザ/jboss7/standalone/configuration/application-users.properties'
Added user 'testuser' to file '/home/ユーザ/jboss7/domain/configuration/application-users.properties'

・コンパイルと実行
$ cd srcclient
$ ant
$ cd ../ejbclient
$ java -classpath $HOME/jboss7/bin/client/jboss-client.jar:. ejbclient
1 02, 2014 4:24:58 午後 org.xnio.Xnio <clinit>
INFO: XNIO Version 3.0.3.GA
1 02, 2014 4:24:58 午後 org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.0.3.GA
1 02, 2014 4:24:58 午後 org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 3.2.3.GA
1 02, 2014 4:24:58 午後 org.jboss.ejb.client.remoting.VersionReceiver handleMessage
INFO: Received server version 1 and marshalling strategies [river]
1 02, 2014 4:24:58 午後 org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate
INFO: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext@3e350808, receiver=Remoting connection EJB receiver [connection=Remoting connection <2befdb3>,channel=jboss.ejb,nodename=naomusi]} on channel Channel ID d65d49fe (outbound) of Remoting connection 395e4ad9 to localhost/127.0.0.1:4447
1 02, 2014 4:24:58 午後 org.jboss.ejb.client.remoting.ChannelAssociation$ResponseReceiver handleMessage
WARN: Unsupported message received with header 0xffffffff
Hello EJB World!


0 件のコメント:

コメントを投稿