Hi,

Here in this demo we will see how to lookup Local EJB3 stateless Bean from a separate Web Application’s Servlet. Where as the EAR containing the Stateless EJB3 and the WAR are separately deployed on the same JBoss AS7 instance. Here we will also discuss the use of different JNDI Names.

The JNDI names for EJB session beans are assigned by the container via the following scheme:

1). Global JNDI
java:global[/<app-name>l]/<module-name>/<bean-name>l[!<fully-qualified-interface-name>l]

java:global JNDI can be used to lookup a resource which is deployed on the same server but as part of a separate application.

2). Application JNDI
java:app/<module-name>l/<bean-name>l[!<fully-qualified-interface-name>l]

java:app JNDI can be used to lookup a resource which is deployed on the same server but as part of the same application.

3). Module JNDI
java:module/<bean-name>l[!<fully-qualified-interface-name>l]

java:module allows a component executing within a Java EE application to access a namespace rooted below the portion of the namespace corresponding to its module.

More details about portable JNDI can be found in the EJB3.1 JSR-318 specification: http://jcp.org/en/jsr/detail?id=318

In this example we will mainly focus on following points

Point-1). Here we are using JBoss AS7 latest build “jboss-as-7.1.0.Alpha2-SNAPSHOT” Download Location :  https://ci.jboss.org/jenkins/job/JBoss-AS-7.x-latest/

Point-2). How to use and develop Servlets without defining servlet-mapping inside the “web.xml” file, while using the @javax.servlet.annotation.WebServlet annotation.

Point-3). How to perform a Local EJB lookup which is deployed as part of a Separate EAR file, with the help of Global JNDI lookup using @javax.ejb.EJB (lookup=””) annotation.

=========

Step1). Create a directory somewhere in your filesystem like “/home/userone/EJB3_LocalLookup_Demo” where we will place our application build related stuff. Then create another directory “src” inside “/home/userone/EJB3_LocalLookup_Demo” where we will be placing our source codes for EJB and WAR files.

Step2). Now we will create a Local Bean Interface “CallerLocal.java” file and Place this file as wll inside the “/home/userone/EJB3_LocalLookup_Demo/src” directory as following:

package caller;
import javax.ejb.*;
@Remote
public interface CallerLocal
{
     public String testMethod(String name);
}

Step3). Now we will create a Simple Stateless EJB with a simple business method to test whether we can invoke this EJB Locally or not. so provide a class inside “/home/userone/EJB3_LocalLookup_Demo/src” directory with name “TestAsyncStatelessSessionBean.java” as following:

package caller;
import javax.ejb.*;
import javax.naming.*;
import java.util.*;
@Stateless(name = "CallerName", mappedName = "CallerMappedName")
public class CallerBean implements CallerLocal
 {
     public String testMethod(String name)
	    {
		   System.out.println("nnt Bean's testMethod(String name) called....");
		   return "[CallerBean] returned Hello "+name;
	    }
 }

Step4). Now we will write the “application.xml” file inside the “/home/userone/EJB3_LocalLookup_Demo” directory to define the EAR application and to define the EJB module inside it as following:

<?xml version="1.0" encoding="UTF-8"?>

<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" id="Application_ID" version="5">
  <display-name>EJB3_localCallDemo</display-name>
  <module>
    <ejb>localEJB.jar</ejb>
  </module>
</application>

Step5). Create Servlet class “TestServlet.java” as following inside the “/home/userone/EJB3_LocalLookup_Demo/src” directory.

package servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.ejb.*;
import javax.servlet.annotation.WebServlet;

@WebServlet(value="/TestServlet")
public class TestServlet extends HttpServlet
  {
     @EJB(lookup="java:global/TestLocalEJBEAR/localEJB/CallerName!caller.CallerLocal")
     private caller.CallerLocal local;
     public void service(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException
       {
            PrintWriter out=res.getWriter();
            out.println("caller.CallerLocal local = "+local);
            out.println("nn");
            out.println("local.testMethod() = "+local.testMethod("MiddlewareMagic"));
       }
  }

Step6). Now the most important part, here we are going to develop “build.xml” ANT file, which will build and deploy our EAR and the WAR applications separately on the JBoss AS7.1 Server, so write the following “build.xml” file inside “/home/userone/EJB3_LocalLookup_Demo” directory.

<project name="SingletonStartupService" default="all">
<property name="jboss.home" value="/home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="src.dir" value="src" />
<property name="output.dir" value="build" />
<property name="ear.name" value="TestLocalEJBEAR.ear" />
<property name="war.name" value="TestWebApp.war" />
<property name="ejb.jar" value="localEJB.jar" />

   <path id="jboss.classpath">
     <fileset dir="${jboss.module.dir}">
        <include name="**/*.jar"/>
     </fileset>  
   </path>

        <target name="init">
           <delete dir="${output.dir}" />
           <mkdir dir="${output.dir}" />
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
        </target>
	 
        <target name="all" depends="deploy" />

        <target name="build_ear">
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
           <javac srcdir="${src.dir}" destdir="${tmp.dir}"  includes="*.java" classpathref="jboss.classpath"/>

           <jar jarfile="${tmp.dir}/${ejb.jar}" basedir="${tmp.dir}" compress="true" />

           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}/caller"/>
           </delete> 
           <mkdir dir="${tmp.dir}/META-INF"/>
           <copy todir="${tmp.dir}/META-INF">
                <fileset dir="${src.dir}/">
                  <include name="application.xml"/> 
                </fileset>
           </copy>           
           <jar jarfile="${tmp.dir}/${ear.name}" basedir="${tmp.dir}" compress="true" />
           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}/META-INF"/>
           </delete> 
           <delete file="${tmp.dir}/${ejb.jar}"/>

           <copy file="${tmp.dir}/${ear.name}" tofile="${output.dir}/${ear.name}"/>
           <delete file="${tmp.dir}/${ear.name}"/>
        </target>


        <target name="build_war">
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}/WEB-INF/classes" />
           <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes"  includes="CallerLocal.java,TestServlet.java" classpathref="jboss.classpath"/>
           <jar jarfile="${output.dir}/${war.name}" basedir="${tmp.dir}" compress="true" />
        </target>        

        <target name="deploy" depends="build_ear,build_war">
            <echo message="*******************  Deploying the EAR file ${ear.name} *********************" />  
            <echo message="********** ${output.dir}/${ear.name} to ${jboss.home}/standalone/deployments **********" />  
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${ear.name}"/> 
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />  
            <echo message="*******************  Deploying the WAR file ${war.name} *********************" />  
            <echo message="********** ${output.dir}/${war.name} to ${jboss.home}/standalone/deployments **********" />  
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${war.name}"/> 
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />  

        </target>
</project>


NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script is to point to your own JBoss AS7 directory home directory.

Step7). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/org.apache.ant_1.6.5/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/org.apache.ant_1.6.5/bin;%PATH%

Step8). Now once the PATH is set In the command/Shell prompt you can move inside the directory “/home/userone/EJB3_LocalLookup_Demo” and then run the ant to build the webservice. by running the command “ant build”

[userone@localhost EJB3_LocalLookup_Demo]$ ant deploy
Buildfile: build.xml

build_ear:
   [delete] Deleting directory /home/userone/EJB3_LocalLookup_Demo/tmp
    [mkdir] Created dir: /home/userone/EJB3_LocalLookup_Demo/tmp
    [javac] Compiling 3 source files to /home/userone/EJB3_LocalLookup_Demo/tmp
      [jar] Building jar: /home/userone/EJB3_LocalLookup_Demo/tmp/localEJB.jar
    [mkdir] Created dir: /home/userone/EJB3_LocalLookup_Demo/tmp/META-INF
     [copy] Copying 1 file to /home/userone/EJB3_LocalLookup_Demo/tmp/META-INF
      [jar] Building jar: /home/userone/EJB3_LocalLookup_Demo/tmp/TestLocalEJBEAR.ear
   [delete] Deleting: /home/userone/EJB3_LocalLookup_Demo/tmp/localEJB.jar
     [copy] Copying 1 file to /home/userone/EJB3_LocalLookup_Demo/build
   [delete] Deleting: /home/userone/EJB3_LocalLookup_Demo/tmp/TestLocalEJBEAR.ear

build_war:
   [delete] Deleting directory /home/userone/EJB3_LocalLookup_Demo/tmp
    [mkdir] Created dir: /home/userone/EJB3_LocalLookup_Demo/tmp/WEB-INF/classes
    [javac] Compiling 2 source files to /home/userone/EJB3_LocalLookup_Demo/tmp/WEB-INF/classes
      [jar] Building jar: /home/userone/EJB3_LocalLookup_Demo/build/TestWebApp.war

deploy:
     [echo] *******************  Deploying the EAR file TestLocalEJBEAR.ear *********************
     [echo] ********** build/TestLocalEJBEAR.ear to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments **********
     [copy] Copying 1 file to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************
     [echo] *******************  Deploying the WAR file TestWebApp.war *********************
     [echo] ********** build/TestWebApp.war to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments **********
     [copy] Copying 1 file to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************

all:

BUILD SUCCESSFUL
Total time: 2 seconds

Step9). Now you will see the following kind of output on your JBoss AS7.1 console which means the applications EAR and the WAR are deployed successfully :

15:39:18,399 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-1) Starting deployment of "TestLocalEJBEAR.ear"
15:39:18,407 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-8) Starting deployment of "localEJB.jar"
15:39:18,438 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-6) JNDI bindings for session bean named CallerName in deployment unit subdeployment "localEJB.jar" of deployment "TestLocalEJBEAR.ear" are as follows:

	java:global/TestLocalEJBEAR/localEJB/CallerName!caller.CallerLocal
	java:app/localEJB/CallerName!caller.CallerLocal
	java:module/CallerName!caller.CallerLocal
	java:global/TestLocalEJBEAR/localEJB/CallerName
	java:app/localEJB/CallerName
	java:module/CallerName

15:39:18,468 INFO  [org.jboss.web] (MSC service thread 1-3) registering web context: /TestWebApp
15:39:18,483 INFO  [org.jboss.as.server.controller] (DeploymentScanner-threads - 2) Replaced deployment "TestLocalEJBEAR.ear" with deployment "TestLocalEJBEAR.ear"
15:39:18,483 INFO  [org.jboss.as.server.controller] (DeploymentScanner-threads - 2) Replaced deployment "TestWebApp.war" with deployment "TestWebApp.war"

Step10). Now access the WebApplication like following : http://localhost:8080//TestWebApp/TestServlet Now you will be able to access the TestServlet which is internally invoking a Business Method of a Local Stateless Bean deployed as part of a Separate EAR file.

NOTE: JBoss AS7 is a Community release and we always recommend you to use the RedHat Supported JBoss Enterprise Application Platform, There are various reasons behind this. Please refer to the Video: http://www.youtube.com/watch?v=iNFV0r9v14g&feature=player_detailpage

.
.
Thanks
Middleware Magic Team

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.