User-defined EJB binding locations were previously ignored in Liberty

In Liberty prior to version 20.0.0.12, Enterprise JavaBeans (EJB) beans were bound only to the java:[scope] namespace. EJB beans were not bound to a server root Java Naming and Directory Interface (JNDI) namespace, which means you could not define the JNDI binding names. EJB binding attributes that allow you to specify the JNDI name in WebSphere Application Server traditional were ignored in Liberty.

The following EJB binding attributes from the ibm-ejb-jar-bnd.xml file were ignored in Liberty.

The following EJB binding attributes from the ibm-ejb-jar-bnd.xmi file were ignored in Liberty.

This rule flags all the JNDI binding names that were ignored in Liberty prior to 20.0.0.12. If your application uses these names in direct JNDI lookups rather than using EJB references, you must use Liberty version 20.0.0.12 or newer or modify your application.

If you use EJB references, the Behavior change on lookups for Enterprise JavaBeans in previous versions of Liberty rule flags any JNDI names that must be converted to the java: namespace if using a version of Liberty older than 20.0.0.12.

If you do not use EJB references and are using a version of Liberty older than 20.0.0.12, it is recommended that you use a newer version of Liberty or create an EJB reference using the same JNDI name and set the EJB reference binding-name to the java:[scope] JNDI name. If you do not add an EJB reference, you must scan your Java code for use of these JNDI names and convert the lookup name to the java: JNDI name.


EJB Migration Example:

The following example creates an EJB reference to help migrate any lookup issues if you are not using Liberty version 20.0.0.12 or newer.

Referenced EJB:

@Stateless
public class MyEJB implements MyEJBInterface {
public String sayHello(String name) {
return "Hello there " + name + ".";
}
}

Remote Interface:

@Remote
public interface MyEJBInterface {
String sayHello(String name);
}

EJB reference examples:

The following are examples on how to declare an EJB Reference in Liberty. Either 1a or 1b is required in conjunction with 2a, 2b, 3a, or 3b to successfully link an EJB and its reference. For example, the recommended options are 1a and 2b for an easy and successful setup, but if 1b is declared in conjunction with 3b you will get the same functionality as the recommended setup.

  1. The reference itself must be declared using an annotation within the class referencing the EJB, in the ejb-jar.xml, or in the web.xml.
    1. EJB Annotation:
      public class TestServlet {
      @EJB(name="ejb/MyEJB")
      MyEJB myEjb;
      ....
      }

    2. ejb-jar.xml and web.xml:
      <ejb-ref>
      <ejb-ref-name>ejb/MyEJB</ejb-ref-name>
      <ejb-ref-type>Session</ejb-ref-type>
      <remote>com.test.MyEJBInterface</remote>
      <ejb-ref>

  2. If the referenced EJB is in the same application as its reference, an ibm-ejb-jar-bnd.xml or ibm-web-bnd.xml entry is not required. One of the following steps will allow the EJB Container to automatically link the EJB and its reference if they are in the same application:

    1. If only one bean in the application implements the remote EJB interface, then no additional configuration is required.

    2. If multiple beans in the application implement the remote EJB interface, then the beanName element must be added to the @EJB annotation. If using an ejb-jar.xml or web.xml, the <ejb-link> element must be added to the existing <ejb-ref> element. Modifications to 1a and 1b are shown here:
      public class TestServlet {
      @EJB(name="ejb/MyEJB" beanName="MyEJB")
      MyEJB myEjb;
      ....
      }

      <ejb-ref>
      <ejb-ref-name>ejb/MyEJB</ejb-ref-name>
      <ejb-ref-type>Session</ejb-ref-type>
      <remote>com.test.MyEJBInterface</remote>
      <ejb-link>MyEJB</ejb-link>
      <ejb-ref>

  3. If the referenced EJB is in a different application than its reference, then one of the following steps must be completed to add a lookup string. These examples show lookup strings for an application running in the same server:

    1. Add the lookup element to the @EJB annotation. If using an ejb-jar.xml or web.xml, the <lookup-name> element must be added to the existing <ejb-ref> element. Modifications to 1a and 1b are shown here:
      public class TestServlet {
      @EJB(name="ejb/MyEJB" lookup="java:global/MyAPP/moduleA/MyEJB!com.test.MyEJBInterface")
      MyEJB myEjb;
      ....
      }

      <ejb-ref>
      <ejb-ref-name>ejb/MyEJB</ejb-ref-name>
      <ejb-ref-type>Session</ejb-ref-type>
      <remote>com.test.MyEJBInterface</remote>
      <lookup-name>java:global/MyAPP/moduleA/MyEJB!com.test.MyEJBInterface</lookup-name>
      <ejb-ref>

    2. Declare the reference binding in the ibm-ejb-jar-bnd.xml or the ibm-web-bnd.xml:
      <ejb-ref name="ejb/MyEJB"
      binding-name="java:global/MyAPP/moduleA/MyEJB!com.test.MyEJBInterface"/>
      The lookup, lookup-name, or binding-name attribute may optionally be used for referencing EJBs in the same application. In that case, the value may be set to any applicable direct EJB lookup described at the end of this page.

The following is the final EJB reference lookup:

public class TestEJBClient {
public static void main(String[] args) {
....
MyEJBInterface myEjbInterface = (MyEJBInterface) context.lookup("java:comp/env/ejb/MyEJB");
}
}

Alternatively, there are three options to lookup an EJB directly, not using an EJB reference:

  1. When a bean is in the same module as its reference:
    public class TestEJBClient {
    public static void main(String[] args) {
    ....
    MyEJBInterface myEjbInterface = (MyEJBInterface) context.lookup("java:module/MyEJB!com.test.MyEJBInterface");
    }
    }

  2. When a bean is in the same application as its reference:
    public class TestEJBClient {
    public static void main(String[] args) {
    ....
    MyEJBInterface myEjbInterface = (MyEJBInterface) context.lookup("java:app/moduleA/MyEJB!com.test.MyEJBInterface");
    }
    }

  3. When the bean definition has to be found globally within the same server:
    public class TestEJBClient {
    public static void main(String[] args) {
    ....
    MyEJBInterface myEjbInterface = (MyEJBInterface) context.lookup("java:global/MyAPP/moduleA/MyEJB!com.test.MyEJBInterface");
    }
    }

For more information on using EJB bindings, see Using enterprise JavaBeans with remote interfaces on Liberty and EJB 3.0 and EJB 3.1 application bindings overview.