Subhankar Nath
Subhankar Nath

Reputation: 3

Referencing EJB Local home from a POJO class of a separate web application

I am trying to port 2 EJB modules in my application from EJB2.1 to EJB3.0. I am using the Eclipse Kepler IDE and regenerated the session beans using an EJB3.0 configuration. I am not using an ejb-jar.xml because in EJB 3.0 that is supposed to be redundant. I have instead used annotations for marking my bean as Stateless and specifying the Local and Local Home Interfaces. I have still kept the Local Home interface since I wanted the basic structure of my project to be similar to what it was in EJB2.1. I have also done away with the xml bindings for the EJB while migrating.

We are using a WAS 7 application server for deployment and while the EJB is getting successfully deployed without errors, I am getting a naming Exception while looking up my Local Home interface from a separate POJO class of a different web application it is required in. I basically want to call the create() method of the Local Home interface after referencing the EJB Local Home. Adding code samples below:

Session Bean:

@Stateless
@Local(AccessLDAPSessionLocal.class)
@LocalHome(AccessLDAPSessionLocalHome.class)
public class AccessLDAPSessionBean implements AccessLDAPSessionLocal {
//Business Logic
}

Local Interface:

public interface AccessLDAPSessionLocal {
//business Interface
}

Local Home Interface:

public interface AccessLDAPSessionLocalHome extends EJBLocalHome {

public AccessLDAPSessionLocal create() throws CreateException;

}

Pojo class referencing the Local Home interface:

public static AccessLDAPSessionLocal getAccessLDAPSessionBean() throws NamingException, CreateException {
    if (accessLDAPSessionBean == null) {
    InitialContext context = new InitialContext();
    Object obj = context.lookup("java:global/AccessLDAP/AccessLDAPSessionBean!com.ibm.asset.hrportal.core.ejb.ldap.AccessLDAPSessionLocalHome");
        accessLDAPSessionBean = ((AccessLDAPSessionLocalHome) obj).create();
    }
    return accessLDAPSessionBean;
}

Also my Local and Local Home interfaces are inside my EJB client which I use as a jar file, while my Session Bean is inside the actual EJB which is used as an EAR.

Following is the error I am getting:

NamingException::javax.naming.NameNotFoundException: Name global not found in context "java:".

Am I missing some configuration resulting in the failure of JNDI lookup? Any help would be gratefully appreciated. Thanks in advance.

Upvotes: 0

Views: 1747

Answers (2)

Brett Kail
Brett Kail

Reputation: 33946

WebSphere Application Server 7.0 is only an implementation of EJB 3.0, but the java:global namespace wasn't added until EJB 3.1, which wasn't implemented in WebSphere Application Server until 8.0. As with all EJB 3.0 implementations, you will need to lookup a vendor-specific binding name. You can find the WebSphere Application Server binding name by looking at the CNTR0167I messages in SystemOut.log. See the EJB 3.0 application bindings overview topic in the Knowledge Center if you would like to customize this binding name.

Regardless, it is not a best practice to directly lookup EJBs by their binding name. Instead, you should use an EJB reference. In EJB 3.0, that means using an annotation like this in an EE managed object (such as a servlet or another EJB):

@EJB 
private AccessLDAPSessionLocalHome home;

In this case, the EJB container is required to find a target EJB within the same application that contains the EJB reference, so you do not need to explicitly configure a target binding name for the EJB reference.

If you need to access the EJB reference from a utility class rather than an EE managed class, then declare the EJB reference with a name on a managed class (such as a servlet or another EJB), and look it up from the utility class:

@EJB(name = "ejb/accessHome", beanInterface = AccessLDAPSessionLocalHome.class)
public class MyServlet { ... }

public class MyUtility {
    ...
    InitialContext context = new InitialContext();
    Object obj = context.lookup("java:comp/env/ejb/accessHome");
    ...
}

You can configure multiple such EJB references on the same managed EE class using the @EJBs annotation:

@EJBs({
    @EJB(name = "ejb/accessHome", beanInterface = AccessLDAPSessionLocalHome.class),
    @EJB(name = "ejb/other" beanInterface = Other.class)
})
public class MyServlet { ... }

If your EJB is packaged in a separate EAR, then note that this is not a portable configuration. See the "Local client views" section of the EJB modules topic in the Knowledge Center. Additionally, you will need to explicitly configure a binding name for the EJB reference.

Upvotes: 2

Sampada
Sampada

Reputation: 2991

I think the way you are looking up the ejb is not correct. The JNDI name would be something like "java:comp/env/". ejb-ref-name would be part of your web.xml

Also, you will need to give providerURL and factoryName to the context object before doing the lookup.

Upvotes: 0

Related Questions