【问题标题】:how JNDI lookup finds a java class?JNDI 查找如何找到 java 类?
【发布时间】:2013-10-26 14:45:01
【问题描述】:

我有一个带有远程接口的 EJB bean。它包含在战争文件 chapter08-service-1.0 中。

@Remote
public interface BookEJBRemote {
    ...
}

在 glassfish 上部署它后,我可以从客户端调用它

Context ctx = new InitialContext();
BookEJBRemote bookEJB = (BookEJBRemote) ctx.lookup("java:global/chapter08-service-1.0/BookEJB!org.agoncal.book.javaee7.chapter08.BookEJBRemote");

它工作正常并调用该方法。但我不明白它是如何找到 EJB 甚至 glassfish 实例的?显然,在查找字符串中没有任何关于 glassfish 的服务器或端口的线索。

【问题讨论】:

  • 它没有“找到 Java 类”。它在命名空间中按名称查找 Java 对象

标签: jakarta-ee ejb rmi


【解决方案1】:

但我不明白如何找到 EJB 甚至 glassfish 实例.实例。

为了通过 JNDI 服务获取 EJB 引用,基本上你需要:

  1. 连接到 JNDI 服务器
  2. 连接后,使用对象名称查找对象 注册。

要连接到 JNDI 服务器,您需要向 InitialContext 对象提供一些信息,例如 JNDI 服务器正在侦听的 ip/port。如here 所述,有多种初始化initialContext 的方法。

如果您不提供此信息,InitialContext 将尝试使用上一个答案中建议的默认端口在 localhost 中搜索服务。

显然没有关于 glassfish 的服务器或端口的线索 查找字符串。

由于上述原因,您不会在查找名称参数中看到 url 或端口信息。

【讨论】:

    【解决方案2】:

    如果您在同一台计算机上运行 glassfish 和您的客户端,则它们可能都使用默认的 JNDI 端口 1099,并且由于两者都在同一台计算机上,因此无需指定主机。

    所以它的工作方式是,您的客户端首先联系 JNDI 服务器,然后 JNDI 服务器返回 EJB 所在的位置(通常是 EJB 可用的主机和端口)。

    我不想听起来消极,但事实证明,EJB 是一种没有兑现承诺的技术,大多数公司很久以前就放弃了 EJB,或者正在努力摆脱它们。

    【讨论】:

    • 这个问题的答案很好,但要避免咆哮
    【解决方案3】:

    InitialContext 只选择一个默认主机 (localhost) 和一个默认端口号。此信息由 glassfish 本身明确设置,这是使用 Java Webstart 技术完成的。

    您可以自己测试它:假设您的应用程序客户端部署到上下文localhost:8080/YourClient。当您访问该链接时,Webstart 正在下载并启动一个 JNLP 文件。您可以手动保存文件,而不是让它自动打开(例如,在 Linux 上是 wget localhost:8080/YourClient)。您会看到 Glassfish 使用很多参数初始化您的客户端应用程序,包括与 JNDI 相关的属性:

    <property name="java.naming.factory.initial" value="com.sun.enterprise.naming.SerialInitContextFactory"/>
    <property name="java.naming.factory.url.pkgs" value="com.sun.enterprise.naming"/>
    <property name="java.naming.factory.state" value="com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl"/>
    <property name="appclient.iiop.defaultHost" value="localhost"/>
    <property name="appclient.iiop.defaultPort" value="${request.appclient.iiop.defaultPort}"/>
    <property name="${appclient.download.host.propertyName}" value="localhost"/>
    <property name="${appclient.user.code.is.signed.propertyName}" value="${appclient.user.code.is.signed}"/>
    

    这些属性不仅仅是为了您的方便而指定的,它们是强制性的。尝试将您的客户端应用程序作为独立应用程序启动(只需在您喜欢的 IDE 中运行主类):在这种情况下,不会设置初始参数。您会注意到,如果没有这些属性,InitialContext 将无法正常工作。

    简短回答您的问题:InitialContext 会找到 Glassfish 和 EJB,因为您的应用程序是使用特殊参数启动的,这些参数告诉 InitialContext 在哪里查找、如何初始化所需的类等。

    【讨论】:

      猜你喜欢
      • 2013-02-22
      • 2016-08-19
      • 2021-04-30
      • 1970-01-01
      • 2013-04-09
      • 2023-03-30
      • 2012-04-24
      • 2019-03-19
      • 2011-08-08
      相关资源
      最近更新 更多