【问题标题】:Error Attempting to Bind EJB in WebSphere Liberty 8.5.5.8尝试在 WebSphere Liberty 8.5.5.8 中绑定 EJB 时出错
【发布时间】:2016-03-31 21:23:31
【问题描述】:

背景:我正在继承一个使用 EJB 的古老应用程序。在项目方面,它列为 3.0 EJB。 EJB 是在运行 WebSphere 6.1 时编写的,其中我们有两个 jvm,一个用于 UI/表示层,另一个 JVM 托管 EJB/“数据层”,它也使用 JPA。我们正在迁移到 WebSphere Liberty 8.5.5.8,当我启动应用程序并访问它时,出现以下异常:

....
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)

下面是访问上下文对象的代码: 提供的失败的 String jndiName 是: "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;
}

我们有两个打包的 EAR 文件,名为 (CHNew.ear) 的 Ear 文件 A 包含一个名为 CHNew.war 的 .war,其中包含大部分前端逻辑,并且在部署程序集中引用了 CHService.jar 文件。名为 (CHService.ear) 的 Ear 文件 B 在名为 CHService.war 的 war 项目中包含 EJB 代码。它们都驻留在同一个应用服务器上,因此是同一个 jvm,但显然没有打包在同一个 ear 文件中。

耳朵A有如下web.xml sn-p:

<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>

编辑:这是 ibm-web-bnx.xml 文件的内容:

<?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>

*我认为过去有一些绑定的 .xmi(注意不是 .xml)文件被忽略了?

在 Ear App B 中有一个 ibm-ejb-jar-bnd.xml 文件,其中包含以下节:

<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>

这是我的 Liberty server.xml 文件:

<!-- 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>

问题:

  1. 我还需要做什么来绑定这个 EJB?
  2. 我已经尝试使用 java:global 命名空间来引用两个 EJB(在同一个 EJB 应用程序中)具有以下 JNDI 名称(它们都引发了 JNDI 命名异常):
    1. java:global/CHServiceEAR/CHService/CHServiceBean!com.xxx.xxx.service.CHSerivceBean
    2. java:global/CHServiceEAR/CHService/CHServiceBean

【问题讨论】:

  • 部署 EAR 时,Websphere 不会将 JNDI 上下文打印到服务器控制台或日志文件?
  • 我在 Liberty 的一个开发环境中,你基本上放下耳朵(或使用添加/删除应用程序)然后 Liberty 加载它们。据我所见,它不会将名称空间转储到日志中。我在 server.xml 中添加了以下内容以启用 jndi 跟踪:

标签: jakarta-ee ejb websphere-liberty


【解决方案1】:

您已经展示了 ibm-ejb-jar-bnd.xml,但您需要展示来自 CHNew.war 的 ibm-web-bnd.xml。错误消息表明您的绑定配置如下:

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

...如果您使用的是 ibm-web-bnd.xmi,或者类似的东西:

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

Liberty 配置文件仅将 EJB 绑定到 java: 命名空间,而从不绑定到默认命名空间(包括像 com.xxx.xxx.service.CHServiceRemote 这样的名称),因此此查找将始终失败。请参阅知识中心中Using enterprise JavaBeans with remote interfaces on Liberty 主题的“命名”部分。您需要将绑定名称更新为 java:global/CHService/CHService/CHServiceBean 之类的名称。有关要使用的确切字符串,请参阅 messages.log 中的 CNTR0167I 消息。

【讨论】:

  • 嗨,Brett,我添加了 ibm-web-bnd.xml 文件的内容。您是说我需要更新 ibm-web-bnd.xml 文件以利用 java:global 命名空间,例如:?
  • @Doug 好吧,由于您使用的是 ibm-web-bnd.xmi(不是 .xml),因此您需要更新到 jndiName="java:global/CHService/CHService/CHServiceBean" 左右,具体取决于消息中的 CNTR0167I 消息。日志,但是是的,您需要更新该绑定名称以使用java:global。我已经更新了答案,以提供指向我写基本相同内容的知识中心的链接。 (仅供参考,您忘记在 ibm-web-bnd.xmi sn-p 中隐藏接口名称。)
  • 所有信息都有帮助。在“CNTR0167I”标题下的 messages.log 中跟踪消息后,我找到了绑定名称。我将它们添加到 ibm-web-bnd.xmi 文件并创建了一个 ibm-web-bnd.xml 文件并添加了指向 jndi 名称的 标记。重新启动后,我不再看到上述错误。我收到与持久性服务相关的新错误,但原始问题已解决。感谢您的帮助!
  • 有趣。 ibm-web-bnd.xmi(带有 ejbRefBindings)始终用于 web 2.x,而 ibm-web-bnd.xml(带有 ejb-ref)始终用于 web 3.0。我猜你曾经有一个 web 2.x 描述符,并且你已经将它升级到 3.0。如果您要将应用程序部署到完整配置文件,它会发出关于 3.0 与 .xmi 不匹配的警告,但我猜 Liberty 配置文件并没有发出警告(还没有?)。
猜你喜欢
  • 1970-01-01
  • 2016-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多