// you're reading...

EJB3.x in Glassfish: 3 Ways to Access Local Stateless Session Bean from EJB, JSP and Servlet

Glassfish is one app server where by accessing Local Stateless Session Bean is a somewhat “confusing” as compared to other App Servers. This post will show you 3 quick, easy, straight forward, no fussed and no debates different ways that you could access your Local Session Beans to get the job done. Yes, only Local Session Beans, NOT Remote Session Beans.


Way No. 1: Accessing Local Stateless Session Bean in another Session Bean

Let say we have 2 session bean, SessionFacade1 and SessionFacade2 as well as their respective interfaces shows in the codes below:

Codes for ISessionFacade1Local:

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
01
package com.developerscrappad.demo.intf;
02
 
03
import javax.ejb.Local;
04
 
05
@Local
06
public interface ISessionFacade1Local
07
{
08
    public double generateRandomNumberStr();
09
}
10

Codes for SessionFacade1:

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
01
package com.developerscrappad.demo.ejb;
02
 
03
import com.developerscrappad.demo.intf.ISessionFacade1Local;
04
import javax.ejb.Stateless;
05
 
06
@Stateless
07
public class SessionFacade1 implements ISessionFacade1Local
08
{
09
    @Override
10
    public double generateRandomNumberStr()
11
    {
12
        return Math.random();
13
    }
14
}

Codes for ISessionFacade2Local:

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
01
package com.developerscrappad.demo.intf;
02
 
03
import javax.ejb.Local;
04
 
05
@Local
06
public interface ISessionFacade2Local
07
{
08
    public String generateLuckyNumberStr();
09
}
10

Codes for SessionFacade2:

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
01
package com.developerscrappad.demo.ejb;
02
 
03
import com.developerscrappad.demo.intf.ISessionFacade1Local;
04
import com.developerscrappad.demo.intf.ISessionFacade2Local;
05
import javax.ejb.EJB;
06
import javax.ejb.Stateless;
07
 
08
@Stateless
09
public class SessionFacade2 implements ISessionFacade2Local
10
{
11
    @EJB
12
    private ISessionFacade1Local sf1Local;
13
 
14
    @Override
15
    public String generateLuckyNumberStr()
16
    {
17
 
18
        double luckyNumber = sf1Local.generateRandomNumberStr() * 1000;
19
        int lNumber = new Double( Math.abs( luckyNumber ) ).intValue();
20
 
21
        return new Integer( lNumber ).toString();
22
    }
23
}

In SessionFacade1, it has a very simple method generateRandomNumberStr() which generates a random number using the java.lang.Math library. As for SessionFacade2, the generateLuckyNumberStr() method will require the business logic from SessionFacade1, perform some manipulation to the number and return it.

Assuming that both EJB and all interface classes is in the same jar file. You can always access the bean itself through tagging the @EJB annotation on the interface declaration.

@EJB
private ISessionFacade1Local sf1Local;

It is that simple, there is no need to declare attributes like beanName or beanInterface in the @EJB annotation. Just plain @EJB will do.

Way No. 2: Accessing Local Stateless Session Bean in Servlet

Just like Way No. 1, @EJB annotation is usable even for a Servlet that is packaged in a different war file. I have a servlet class below which calls the generateLuckyNumberStr() from SessionFacade2 and prints the number as HTML.

Codes for LuckyNumberServlet:

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
01
package com.developerscrappad.jspstuff;
02
 
03
import com.developerscrappad.demo.intf.ISessionFacade2Local;
04
import java.io.IOException;
05
import java.io.PrintWriter;
06
import javax.ejb.EJB;
07
import javax.servlet.ServletException;
08
import javax.servlet.http.HttpServlet;
09
import javax.servlet.http.HttpServletRequest;
10
import javax.servlet.http.HttpServletResponse;
11
 
12
public class LuckyNumberServlet1 extends HttpServlet
13
{
14
    @EJB
15
    private ISessionFacade2Local sf2;
16
 
17
    public LuckyNumberServlet1()
18
    {
19
        super();
20
    }
21
 
22
    protected void processRequest( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
23
    {
24
        response.setContentType( "text/html;charset=UTF-8" );
25
        PrintWriter out = response.getWriter();
26
 
27
        try
28
        {
29
            out.println( "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">" );
30
            out.println( "<title>My Lucky Number</title></head>" );
31
            out.println( "<body><h1>" );
32
            out.print( sf2.generateLuckyNumberStr() );
33
            out.print( "</h1></body>" );
34
            out.println( "</html>" );
35
 
36
        }
37
        catch ( Exception ex )
38
        {
39
            throw new ServletException( ex );
40
        }
41
        finally
42
        {
43
            out.close();
44
        }
45
    }
46
 
47
    @Override
48
    protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
49
    {
50
        processRequest( request, response );
51
    }
52
 
53
    @Override
54
    protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
55
    {
56
        processRequest( request, response );
57
    }
58
}
59

Just as the example in Way No. 1, the servlet could automatically inject the sf1Local variable declaration through injection with the @EJB annotation. This is perfectly legitimate.

Way No. 3: Access Local Stateless Session Bean in JSP and Other Classes or Business Components

This is a tricky one and somewhat confusing to many developers. Unfortunately till now, there are limitations from Glassfish App Server to allow direct @EJB injection of Local Stateless Session Bean. Instead, the way to access it is through inserting snippets of <ejb-local-ref> in the web.xml and through a JNDI call.

By using the same Stateless Session Beans from the above examples: SessionFacade1 and SessionFacade2, first, we have to insert the <ejb-local-ref> tag into the web.xml file like the below:

<ejb-local-ref>
    <ejb-ref-name>SessionFacade2RefName</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local>com.developerscrappad.demo.intf.ISessionFacade2Local</local>
    <ejb-link>LocalEJBDemo-ejb.jar#SessionFacade2</ejb-link>
</ejb-local-ref>

I’ll just give a reference name as SessionFacade2RefName and do take note that since my EJB is packaged in another jar “LocalEJBDemo-ejb.jar”, the <ejb-link> value should be the EJB name in the jar file that it is being packaged. However, <ejb-link> is optional and you can do without it.

Once after having the <ejb-local-ref> tag in the web.xml file, you can call the EJB through JNDI at the below:

String prefix = "java:comp/env/";
String ejbRefName = "SessionFacade2RefName";

String jndiUrl = prefix + ejbRefName;    //The JNDI URL should be "java:comp/env/SessionFacade2RefName"
javax.naming.Context ctx = new javax.naming.InitialContext();
ISessionFacade2Local sf2 = ( ISessionFacade2Local ) ctx.lookup( jndiUrl );

String result =  sf2.generateLuckyNumberStr();

So far, we can only access Local Stateless Session Bean in JSP, class or a business component through JNDI call and make sure that <ejb-local-ref> tag is declared in the web.xml file.

Summary

This sums up the simple 3 ways that we could access Local Session Beans from either through another EJB, a JSP or a Servlet. There are reasons why Glassfish or the JSR specs would not allow the @EJB way in JSPs but I’m not going to write them here as it is not the objective of this article.

** Do take note that if you are calling a local Stateful Session Bean, it is most advisable to always access it through the JNDI call, instead of the @EJB injection, as the JNDI call will always ensure that the beans returned is of the most recent state.

Hope it helps.

Previous Posts

Java LDAP/JNDI: 2 Ways Of Decoding And Using The objectGUID From Windows Active Directory

Java LDAP/JNDI: 2 Ways Of Decoding And Using The objectGUID From Windows Active Directory

October 13th, 2012

Windows Active Directory is a good way for many corporations to be used as a means of user managemen[...]

Quick Note: Unable To Perform LDAP Wildcard “*” Search On Windows Active Directory

Quick Note: Unable To Perform LDAP Wildcard "*" Search On Windows Active Directory

October 9th, 2012

In case you are searching high and low for a solution or an answer to why Windows Active Directory d[...]

Java JNDI/LDAP: Windows Active Directory Authentication, Organizational Unit, Group & Other Information Access

Java JNDI/LDAP: Windows Active Directory Authentication, Organizational Unit, Group & Other Information Access

October 4th, 2012

In today's IT environment, most mid-size corporation and above will have some form of centralized em[...]

MySQL Cluster NDB 7.2 on Solaris 10 Part 3 – Testing The Cluster

MySQL Cluster NDB 7.2 on Solaris 10 Part 3 - Testing The Cluster

September 22nd, 2012

We are back again to have fun with our cluster that we've setup written in our previous articles on [...]

MySQL Cluster NDB 7.2 on Solaris 10 Part 2 – Starting, Distributed Synchronized Users Management And Stopping The Cluster

MySQL Cluster NDB 7.2 on Solaris 10 Part 2 - Starting, Distributed Synchronized Users Management And Stopping The Cluster

September 18th, 2012

This is the continuation from the previous part of the tutorial MySQL Cluster NDB 7.2 on Solaris 10 [...]

MySQL Cluster NDB 7.2 on Solaris 10 Part 1 – How To Install, Setup and Configure

MySQL Cluster NDB 7.2 on Solaris 10 Part 1 - How To Install, Setup and Configure

September 18th, 2012

If you have landed on this page, we believe you might either had a bumpy ride in getting the MySQL c[...]

Quick Fix: How to Solve “Unable to read the logging configuration” on Netbeans7 with JBoss6

Quick Fix: How to Solve "Unable to read the logging configuration" on Netbeans7 with JBoss6

September 8th, 2012

This is just a quick fix post for those whom are having this problem when running JBoss 6.x with Net[...]

Making sense of EJB3.x Transaction Attributes – Part 4 (NEVER)

Making sense of EJB3.x Transaction Attributes – Part 4 (NEVER)

September 5th, 2012

This is the last part in the series of "Making sense of EJB3.x Transaction Attributes". So far, we'v[...]

Making sense of EJB3.x Transaction Attributes – Part 3 (Difference Between SUPPORTS and NOT_SUPPORTED)

Making sense of EJB3.x Transaction Attributes – Part 3 (Difference Between SUPPORTS and NOT_SUPPORTED)

September 5th, 2012

Oracle had extensively documented the behavior of each transaction attributes in the Java EE documen[...]