0

正如标题所说。我在 EAR 中有一些 EJB,并且我有一个客户端 jar,它为同样处于自由状态(不同的服务器/机器)的 JSF 应用程序提供远程方法。客户端 jar 尝试通过查找访问远程 EJB。

这让我心碎了两天。正如标题所说...

我知道过去的其他 stackoverflow 问题,并且我知道以下资源: https ://www.ibm.com/docs/en/was-liberty/core?topic=liberty-using-enterprise-javabeans-remote -接口

https://github.com/OpenLiberty/open-liberty/blob/release/dev/com.ibm.ws.ejbcontainer.remote_fat/test-applications/RemoteClientWeb.war/src/com/ibm/ws/ejbcontainer/remote/客户端/web/RemoteTxAttrServlet.java

我已经尝试了上面提供的所有组合,但没有任何乐趣。


我使用启用了 javaee8 功能的 (wlp-javaee8.21.0.0.8),这启用了我需要的所有其他东西,例如 ejb-3.2、ejbRemote-3.2、jndi-1.0 和其他一些)

我有一个 EAR my-ear,其中包含一个模块 my-module-1.0.4-SNAPSHOT.jar,其中包含我的 bean。我正在使用 gradle/liberty 插件和 IntelliJ。我在客户端 jar 模块中使用 IntelliJ 中的测试来尝试访问远程 bean。

我的 myEAR 部署良好,启动良好,应用程序显示在 admincenter 中运行。在messages.log 中,我看到了我的EJB 绑定。只举一个例子。

[16/08/21 10:58:42:384 IST] 00000022 com.ibm.ws.ejbcontainer.osgi.internal.NameSpaceBinderImpl I CNTR0167I:服务器正在绑定 my.org.functiona.ejb.advance.MyAdvance 接口my-ear 应用程序的 my-module-1.0.4-SNAPSHOT.jar 模块中的 MyAdvanceBean 企业 bean。绑定位置是:ejb/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean#my.org.functiona.ejb.advance.MyAdvance [16/08/21 10:58:42:385 IST ] 00000022 com.ibm.ws.ejbcontainer.osgi.internal.NameSpaceBinderImpl I CNTR0167I: 服务器正在绑定 my-module-1.0.4- 中 MyAdvanceBean 企业 bean 的 my.org.functiona.ejb.advance.MyAdvance 接口my-ear 应用程序的 SNAPSHOT.jar 模块。绑定位置是:my.org.functiona.ejb.advance.MyAdvance [16/08/21 10:58:42:385 IST] 00000022 com.ibm.ws.ejbcontainer.runtime.AbstractEJBRuntime
I CNTR0167I: 服务器正在绑定 my-ear 应用程序的 my-module-1.0.4-SNAPSHOT.jar 模块中的 MyAdvanceBean 企业 bean 的 my.org.functiona.ejb.advance.MyAdvance 接口。绑定位置为:java:global/my-ws-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean!my.org.functiona.ejb.advance.MyAdvance

这是我对应的界面:

package my.org.functiona.ejb.advance;

import javax.ejb.Remote;

@Remote
public interface MyAdvance {

这是我相应的实现:

package my.org.functiona.ejb.advance;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;

@Stateless(mappedName = "MyAdvance")
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class MyAdvanceBean implements MyAdvance {

就像我说的,它伤透了我的心。我尝试了(不完整的)文档和其他来源中提供的每种组合。我取得的最大进展是通过默认 InitialContext().lookup 访问“corbaname::localhost:2809/NameService”。所以至少我能够确认我可以连接到 NameService。但是,使用该上下文以及 messages.log 或文档中的代码片段中提供的任何名称组合的任何后续 bean 查找都会失败,但出现以下异常。

javax.naming.NameNotFoundException [根异常是 org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]

与 InitialContext() 查找相同,我在名称前加上“corbaname::localhost:2809/NameService#”。

我试过了

  • ejb/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean#my.org.functiona.ejb.advance.MyAdvance
  • ejb/global/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean#my.org.functiona.ejb.advance.MyAdvance
  • ejb/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvance#my.org.functiona.ejb.advance.MyAdvance
  • ejb/global/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvance#my.org.functiona.ejb.advance.MyAdvance
  • java:global/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvance#my.org.functiona.ejb.advance.MyAdvance
  • java:global/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean#my.org.functiona.ejb.advance.MyAdvance
  • my.org.functiona.ejb.advance.MyAdvance

可能还有其他几个

我在上面的所有内容中都用感叹号替换了 # 符号。又经历了一遍。我尝试了 corbaloc:: 和 corbaloc:iiop: 作为上下文。没有什么。

我不是网络开发专家,但这感觉非常尝试和错误,我不觉得它应该是那样的。我知道在 websphere 中,我可以在管理控制台中识别名称,但是我什至不确定 websphere 本身和 liberty 的行为方式相同。

正弦从远程访问 EJB 似乎是面包和黄油的东西我认为由于我的经验不足,我忽略了一些基本和愚蠢的东西。

任何指针任何人?非常感谢您花时间阅读本文。

卡斯滕

编辑:server.xml

<server description="disbCoreServer">

  <featureManager>
    <feature>javaee-8.0</feature>
    <feature>adminCenter-1.0</feature>
    <feature>websocket-1.1</feature>
  </featureManager>

  <quickStartSecurity userName="admin" userPassword="carsten" />

  <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
  <httpEndpoint id="defaultHttpEndpoint"
                host="${hostname}"
                httpPort="${default.http.port}"
                httpsPort="${default.https.port}">
      <accessLogging filepath="${com.ibm.ws.logging.log.directory}/accessLog.log" logFormat='%h %i %u %t "%r" %s %b %{R}W' />
      <tcpOptions soReuseAddr="true" />
  </httpEndpoint>

  <include location="appConfXML/disb_core_jndi.xml"/>
  <include location="appConfXML/disb_core_jdbc.xml"/>
  <include location="appConfXML/disb_core_jms.xml"/>
  <include location="appConfXML/disb_core_mail.xml"/>

</server>
4

1 回答 1

0

通过 FAT 测试 (remoteLookup) 提供的示例运行良好。我只是没有连续吃掉所有的鸭子。

https://github.com/OpenLiberty/open-liberty/blob/release/dev/com.ibm.ws.ejbcontainer.remote_fat/test-applications/RemoteClientWeb.war/src/com/ibm/ws/ejbcontainer/remote/客户端/web/RemoteTxAttrServlet.java

我的场景是 serverA 托管 EJB,serverB 运行远程客户端调用 serverA 的 EJB。

serverB 上的步骤是:

  1. 获取(本地)不带属性的 InitialContext:InitialContext initialContext = new InitialContext();

  2. 通过上面的查找远程上下文:Context remoteContext = (Context) initialContext.lookup("corbaname::remotehost:remotePort/NameService");

  3. 使用 remoteContext 查找 EJB 远程接口并“缩小”并将它们转换为适当的类型

    String lookupName = "ejb/global" + "/" + "MyAppName" + "/" + "MyModuleName" + "/" + jndiName; Object remoteObj = remoteContext.lookup(lookupName); return interfaceClass.cast(PortableRemoteObject.narrow(remoteObj, interfaceClass));

    在哪里

    • “MyAppName”是我的应用程序名称,在我的例子中是 EAR 的名称(不带 .jar)
    • “MyModuleName”是我的 EAR 中 EJB 模块的名称(不带 .jar)
    • jndiName 是由感叹号分隔的 bean 名称/完全限定的接口名称,例如“MyBean!myorg.ejb.interfaces.MyBeanIfc”
  4. 调用接口远程执行serverA EJB代码

注意:在同一台机器(例如本地主机)上运行 serverA 和 serverB 时,请确保它们不在 NameService 的同一端口上运行。

感谢所有试图提供帮助的人!

于 2021-09-16T11:26:41.590 回答