Sunday, January 17, 2016

EJB and JNDI, or how to lookup a EJB from a JSP

package ejb3.bean;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

@Stateless(mappedName = "HelloEjb")
public class HelloEjb implements HelloEjbRemote, HelloEjbLocal {

 public HelloEjb() {

 public String printHello(String name) {
  return "Hello " + name;


package ejb3.bean;

import javax.ejb.Remote;

public interface HelloEjbRemote {
 String printHello(String name);

package ejb3.bean;

import javax.ejb.Local;

public interface HelloEjbLocal {
 String printHello(String name);

The LocalBean means a no-interface view .

This is what I find in JNDI tree:

Binding Name: HelloEjb#ejb3.bean.HelloEjbRemote (this is from @Remote)
Class: com.sun.proxy.$Proxy208

Binding Name: java:global.PVHelloEJBEAR.PVHelloEJB.HelloEjb!ejb3.bean.HelloEjb (this is from @LocalBean )
Class: ejb3.bean.HelloEjb_n3seu_NoIntfViewImpl

Binding Name: java:global.PVHelloEJBEAR.PVHelloEJB.HelloEjb!ejb3.bean.HelloEjbLocal (this is from @Local)
Class: ejb3.bean.HelloEjb_n3seu_HelloEjbLocalImpl

Binding Name: java:global.PVHelloEJBEAR.PVHelloEJB.HelloEjb!ejb3.bean.HelloEjbRemote (this is from @Remote again)
Class: com.sun.proxy.$Proxy208

where PVHelloEJBEAR.PVHelloEJB.HelloEjb are respectively: application name (from application.xml), ejb module name (from application.xml), ejb name (mappedName)
To lookup the EJB interface from a JSP:
HelloEjbRemote helloEjb = (HelloEjbRemote) context.lookup("HelloEjb#ejb3.bean.HelloEjbRemote");

or (it works also in a servlet) if the JSP is in a WAR the same EAR as the EJB module you can use the no-interface @LocalBean trick :
private HelloEjb helloEjb;

If you provide a @EJB in the JSP/Servlet without having a @LocalBean annotation, you get this error:
Module named 'PVHelloEJBEAR' failed to redeploy. See Error Log view for more detail. weblogic.application.naming.ReferenceResolutionException: [J2EE:160200]Error resolving ejb-ref "ejb3.bean.HelloEjb3Servlet/helloEjb" from module "PVHelloWAR.war" of application "PVHelloEJBEAR". The ejb-ref does not have an ejb-link and the JNDI name of the target bean has not been specified. Attempts to automatically link the ejb-ref to its target bean failed because no EJBs in the application were found to implement the "ejb3.bean.HelloEjb" interface. Link or map this ejb-ref to its target EJB and ensure the interfaces declared in the ejb-ref are correct.
Exception received from deployment driver. See Error Log view for more detail.

This is the documentation of @EJB :

So if from your Servlet/JSP you want to access a REMOTE EJB (i.e. without LocalBean) you must change your @EJB lookup to:
private HelloEjbRemote helloEjb;

or using the @Local interface:
private HelloEjbLocal helloEjb;

Sample project available:
git clone
cd JavaMonAmour\jeesamples\HelloEJB

If you wonder about Portable JNDI Syntax, have a look here.

No comments: