How to Override an @EJB Reference

I found this very simple in the end, but tracking it down and getting the concepts right was surprisingly difficult.  What follows is just my rephrasing of all the bits—it’s nothing revolutionary.

When you use the @EJB annotation in any way, shape or form, you declare an EJB reference.  You say, “I am going to use an EJB, and directly or indirectly I’m going to look for it under a particular name in my java:comp/env JNDI namespace.”  The actual JNDI lookup may be hidden, but it is important to realize that at least conceptually it is always there.

If you use the name attribute of the @EJB annotation, then you are also saying: “In addition to declaring an EJB reference, I’m also (for whatever reason) going to give this reference a name.”  You can name it anything you want.  The value you supply to the name attribute of the @EJB annotation will be relative (in JNDI) to java:comp/env. This name does not intrinsically identify a bean. It identifies a “slot” in JNDI where a bean is expected to reside such that your bean can find it. Making a bean arrive in this slot is the container’s responsibility, or the Application Assembler’s responsibility.

If you do not use the name attribute of the @EJB annotation, then it is exactly as though you supplied classname/fieldname as a value for the name attribute (if you annotated a field, the most common case). That is, the following two snippets are exactly equal:


package foo;
@Stateless
public class CaturgiatorBean {
@EJB
private Frobnicator frobnicator;
}

The following snippet spells out what was only implied above:


package foo;
@Stateless
public class CaturgiatorBean {
@EJB(name = "foo.CaturgiatorBean/frobnicator")
private Frobnicator frobnicator;
}

If you put an @EJB annotation on a class, you are saying: “In this class, somewhere, someone will look up an EJB under a particular name in JNDI.  Please be prepared for this to happen so they don’t get a NullPointerException or something worse.” This usage of @EJB doesn’t do anything besides simply declare that the bean will be looking for something in a given slot in JNDI.

The @EJB annotation is equal to either the <ejb-local-ref> or <ejb-ref> deployment descriptor element. If you used it on a field whose type is a local business interface of another EJB somewhere, then it’s as though you specified an <ejb-local-ref> in the deployment descriptor.

The minimal way to override a situation like either of the examples above using an ejb-jar.xml file is to include the following snippet:


<?xml version="1.0" ?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
version="3.1">
<enterprise-beans>
<session>
<ejb-name>ReferencingBeanName</ejb-name>
<ejb-local-ref>
<ejb-ref-name>referencing.bean.pkg.ReferencingBean/fieldStoringReferencedBeanProxy</ejb-ref-name>
<ejb-link>ReferencedBeanName</ejb-link>
</ejb-local-ref>
</session>
</enterprise-beans>
</ejb-jar>

view raw

ejb-jar.xml

hosted with ❤ by GitHub

Advertisement

Author: Laird Nelson

Devoted husband and father; working on Helidon at the intersection of Java, Jakarta EE, architecture, Kubernetes and microservices at Oracle; open source guy; Hammond B3 player and Bainbridge Islander.

%d bloggers like this: