0

Background: I am inheriting an ancient application that utilizes EJBs. In the facet of the project it lists as a 3.0 EJB. The EJB was written while running WebSphere 6.1 where we had two jvms, one for UI/Presentation Layer and a second JVM that hosted the EJB / "data layer" which is also using JPA. We are moving to WebSphere Liberty 8.5.5.8 and when I start my application and access it, I get the following exception:

....
Caused by: 
com.ibm.wsspi.injectionengine.InjectionException: CWNEN0030E: The server was unable to obtain an object instance for the java:comp/env/ejb/CHServiceBean reference.  The exception message was: CWNEN1003E: The server was unable to find the com.xxx.xxx.service.CHServiceRemote binding with the com.xxx.xxx.service.CHService type for the java:comp/env/ejb/CHServiceBean reference.
    at com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1458)
    at com.ibm.ws.ejb.injection.processor.EJBInjectionBinding.getInjectionObject(EJBInjectionBinding.java:1047)
    at com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1389)
    at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getObjectInstance(InjectionJavaColonHelper.java:116)
    ... 44 more
Caused by: 
com.ibm.wsspi.injectionengine.InjectionException: CWNEN1003E: The server was unable to find the com.xxx.xxxx.service.CHServiceRemote binding with the com.xxx.xxxxx.service.CHService type for the java:comp/env/ejb/CHServiceBean reference.
    at com.ibm.ws.injectionengine.osgi.internal.IndirectJndiLookupObjectFactory.getObjectInstance(IndirectJndiLookupObjectFactory.java:202)

Here is the code that is accessing the context object: The supplied String jndiName that is failing is: "java:comp/env/ejb/CHServiceBean"

public Object getResource(String jndiName) throws Exception {
    Object obj = null;
    if (obj == null) {
        try {
            obj = new InitialContext().lookup(jndiName);
            return obj;
        } catch (Exception e) {
            XXXXXX.error("ServiceLocator.getResource(...) ERROR, "");
            throw e;
        }
    }
    return obj;
}

We have two packaged EAR files, Ear file A called (CHNew.ear) which contains a .war called CHNew.war that contains most of the front end logic and in the deployment assembly references the CHService.jar file. Ear file B called (CHService.ear) houses the EJB code in a war project called CHService.war. They both reside on the same application server and thus the same jvm but are obviously not packaged in the same ear file.

Ear A has the following web.xml snippet:

<ejb-ref id="EjbRef_1430884948507">
  <description>
  </description>
  <ejb-ref-name>ejb/CHServiceBean</ejb-ref-name>
  <ejb-ref-type>Session</ejb-ref-type>
  <home>com.xxx.xxx.service.CHService</home>
  <remote>com.xxx.xxx.service.CHServiceRemote</remote>
</ejb-ref>
<ejb-ref id="EjbRef_1430885115133">
  <ejb-ref-name>ejb/CHServiceBeanRO</ejb-ref-name>
  <ejb-ref-type>Session</ejb-ref-type>
  <home>com.xxx.xxxx.service.CHServiceRO</home>
  <remote>com.xxx.xxx.service.CHServiceRemoteRO</remote>
</ejb-ref>

EDIT: Here is the contents of the ibm-web-bnx.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<webappbnd:WebAppBinding xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:webappbnd="webappbnd.xmi" xmi:id="WebAppBinding_1430419801447" virtualHostName="default_host">
  <webapp href="WEB-INF/web.xml#WebApp_ID"/>
  <resRefBindings xmi:id="ResourceRefBinding_1430749102271" jndiName="services/cache/CHContacts">
    <bindingResourceRef href="WEB-INF/web.xml#ResourceRef_1430749102271"/>
  </resRefBindings>
  <resRefBindings xmi:id="ResourceRefBinding_1436377001246" jndiName="jdbc/nextgen">
    <bindingResourceRef href="WEB-INF/web.xml#ResourceRef_1436377001246"/>
  </resRefBindings>
  <resRefBindings xmi:id="ResourceRefBinding_1436377001247" jndiName="jdbc/nextgen_RO">
    <bindingResourceRef href="WEB-INF/web.xml#ResourceRef_1436377001247"/>
  </resRefBindings>
  <resRefBindings xmi:id="ResourceRefBinding_1456409466488" jndiName="services/cache/CHGeneric">
    <bindingResourceRef href="WEB-INF/web.xml#ResourceRef_1456409466488"/>
  </resRefBindings>
  <ejbRefBindings xmi:id="EjbRefBinding_1430884948507" jndiName="com.xxx.xxx.service.CHServiceRemote">
    <bindingEjbRef href="WEB-INF/web.xml#EjbRef_1430884948507"/>
  </ejbRefBindings>
  <ejbRefBindings xmi:id="EjbRefBinding_1430885115133" jndiName="com.xxx.xxx.service.CHServiceRemoteRO">
    <bindingEjbRef href="WEB-INF/web.xml#EjbRef_1430885115133"/>
  </ejbRefBindings>
</webappbnd:WebAppBinding>

*There are binding .xmi (note not .xml) files from the past which I believe are ignored?

In the Ear App B there is an ibm-ejb-jar-bnd.xml file that contains the following stanza:

<session name="CHServiceBean">
  <resource-ref name="jdbc/db" binding-name="jdbc/db"></resource-ref>
  <resource-ref name="services/cache/CacheA" binding-name="services/cache/CHBluepages"></resource-ref>
  <resource-ref name="services/cache/CacheB" binding-name="services/cache/CHGeneric" ></resource-ref>
</session>

<session name="CHServiceBeanRO">
  <resource-ref name="jdbc/db_RO"
      binding-name="jdbc/db_RO">
  </resource-ref>
  <resource-ref name="jdbc/db" binding-name="jdbc/db"></resource-ref>
  <resource-ref name="services/cache/CHGeneric" binding-name="services/cache/CHGeneric"></resource-ref>
  <resource-ref name="services/cache/CacheA" binding-name="services/cache/CacheB"></resource-ref>
</session>

Here is my Liberty server.xml file:

<!-- Enable features -->
    <featureManager>
        <feature>javaee-7.0</feature>
        <feature>localConnector-1.0</feature>
        <feature>distributedMap-1.0</feature>
        <feature>adminCenter-1.0</feature> 
        <feature>ssl-1.0</feature>
        <feature>usr:webCacheMonitor-1.0</feature>
        <feature>webCache-1.0</feature>
        <feature>ldapRegistry-3.0</feature>
    </featureManager>

    <!--  Admin Center Config Start -->
    <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
    <httpEndpoint host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>

    <keyStore id="defaultKeyStore" password="xxxxxx"/> 

    <basicRegistry id="basic"> 
          <user name="wpsadmin" password="xxxxxx"/> 
    </basicRegistry> 

    <administrator-role> 
      <user>wpsadmin</user>
    </administrator-role>

    <remoteFileAccess> 
       <writeDir>${server.config.dir}</writeDir> 
    </remoteFileAccess>

    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>
    <applicationMonitor updateTrigger="mbean"/>

    <enterpriseApplication id="CHNewCHRDMEAR" location="CHNewCHRDMEAR.ear" name="CHNewCHRDMEAR">
        <application-bnd>
            <security-role name="AllAuthenticated">
                <special-subject type="ALL_AUTHENTICATED_USERS"/>
            </security-role>
        </application-bnd>
    </enterpriseApplication>
    <enterpriseApplication id="CHServiceEAR" location="CHServiceEAR.ear" name="CHServiceEAR"/>

    <!--  JAAS Authentication Alias (Global) Config -->
    <authData id="r4dba" password="{xor}MzhmJT06ajI=" user="r4dba"/>

    <!--  JDBC Driver and Datasource Config -->
    <library id="DB2JCC4Lib">
        <fileset dir="C:\DB2\Jars" includes="db2jcc4.jar db2jcc_license_cisuz.jar"/>
    </library>
</server>

Questions:

  1. What else do I need to do to bind this EJB?
  2. I have tried using the java:global namespace to reference the two EJBs (in the same EJB applcation) with the following JNDI names (which all threw JNDI naming exceptions):
    1. java:global/CHServiceEAR/CHService/CHServiceBean!com.xxx.xxx.service.CHSerivceBean
    2. java:global/CHServiceEAR/CHService/CHServiceBean
Doug
  • 145
  • 2
  • 14
  • When you deploy your EARs, Websphere doesn't print the JNDI contexts to the server console or log file? – António Ribeiro Mar 31 '16 at 22:51
  • I am in a development env in Liberty, you essentially drop the ears (or use Add / Remove Apps) and Liberty loads them. As far as I can see it doesn't dump the namepsace to a log. I added the following to my server.xml to enable jndi tracing: – Doug Apr 01 '16 at 16:07

1 Answers1

2

You've shown the ibm-ejb-jar-bnd.xml, but you need to show the ibm-web-bnd.xml from CHNew.war. The error message suggests you have a binding configured like:

<ejb-ref name="ejb/CHServiceBean" binding-name="com.xxx.xxx.service.CHServiceRemote">

...or something like this if you're using ibm-web-bnd.xmi:

  <ejbRefBindings xmi:id="EjbRefBinding_1430884948507" jndiName="com.xxx.xxx.service.CHServiceRemote">
    <bindingEjbRef href="WEB-INF/web.xml#EjbRef_1430884948507"/>
  </ejbRefBindings>

The Liberty profile only binds EJBs to the java: namespace and never to the default namespace (which includes names like com.xxx.xxx.service.CHServiceRemote), so this lookup will always fail. See the "Naming" section of the Using enterprise JavaBeans with remote interfaces on Liberty topic in the Knowledge Center. You need to update the binding-name to something like java:global/CHService/CHService/CHServiceBean. See the CNTR0167I message in messages.log for the exact string to use.

Brett Kail
  • 33,593
  • 2
  • 85
  • 90
  • Hi Brett, I added the contents of the ibm-web-bnd.xml file. Are you saying that I need to update the ibm-web-bnd.xml file to utilize the java:global namespace, for example something like this: ? – Doug Apr 01 '16 at 15:45
  • @Doug Well, since you're using ibm-web-bnd.xmi (not .xml), you'll need to update to `jndiName="java:global/CHService/CHService/CHServiceBean"` or so depending on the CNTR0167I message in messages.log, but yes, you need to update that binding name to use `java:global`. I've updated the answer to give a link to the Knowledge Center where I wrote basically the same thing. (FYI, you forgot to blind the interface name in your ibm-web-bnd.xmi snippet.) – Brett Kail Apr 01 '16 at 16:55
  • all the info helped. After tracking down the messages in the messages.log under the "CNTR0167I" header I found the binding names. I added them to the ibm-web-bnd.xmi file and created an ibm-web-bnd.xml file and added the tag pointing to the jndi name. After restart I no longer see the above error. I get a new error related to the persistence service but the original issue is resolved. Thanks for your help! – Doug Apr 01 '16 at 19:56
  • Interesting. ibm-web-bnd.xmi (with ejbRefBindings) is always used for web 2.x and ibm-web-bnd.xml (with ejb-ref) is always used for web 3.0. I guess you used to have a web 2.x descriptor and you've since upgraded it to 3.0. If you were to deploy the app to full profile, it would give a warning about the mismatched 3.0 with .xmi, but I guess Liberty profile doesn't warn about that (yet?). – Brett Kail Apr 01 '16 at 20:14