【问题标题】:Does OSGI JNDI allow coexistence with JNDI calls from non-OSGI code?OSGI JNDI 是否允许与来自非 OSGI 代码的 JNDI 调用共存?
【发布时间】:2012-11-20 21:31:46
【问题描述】:

OSGI Enterprise Release 5 specification 的第 126 章提到了兼容性:

“支持 Java SE 和 Java EE 客户端使用的传统 JNDI 编程模型。”

以及使用不支持 OSGI 的代码:

“不知道 OSGi 的客户端和 JNDI 上下文提供程序使用静态方法连接到 JRE JNDI 实现。 InitialContext 类提供从提供者对 Context 的访问,并且 提供者使用静态 NamingManager 方法进行对象转换和查找 URL 上下文。 这种传统模型不了解 OSGi,因此只有在出现后果的情况下才能可靠地使用 对这种缺乏 OSGi 意识的情况进行了管理。”

但我不清楚此文本是否仅适用于在 OSGI 包内执行的“遗留”代码,或者也适用于 OSGI 容器外部的代码,例如在 OSGI 容器嵌入应用程序的情况下。

在嵌入场景中,OSGI 容器外部和内部都可能存在执行 JNDI 调用的应用程序代码,并且当它们在同一个 JVM 中执行时,它们将共享 JNDI 实现。

问题:在嵌入式 OSGI 容器中运行的 OSGI JNDI 实现是否应该允许容器外部的不支持 OSGI 的代码像往常一样执行其 JNDI 调用,或者是否需要移植到“OSGI 感知”? ?

我自己用 Apache Karaf 2.3.0(它使用 Apache Aries JNDI 1.0.0)尝试这个似乎不起作用,因为 Apache Aries 需要来自 OSGI 包的 JNDI 客户端调用。
部分堆栈跟踪:

javax.naming.NoInitialContextException: The calling code's BundleContext could not be determined.
    at org.apache.aries.jndi.OSGiInitialContextFactoryBuilder.getInitialContext(OSGiInitialContextFactoryBuilder.java:46)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
    at javax.naming.InitialContext.init(InitialContext.java:242)
    at javax.naming.InitialContext.<init>(InitialContext.java:192)

问题:这是正确的行为,还是我可以参考的规范中的某个部分违反了此限制?

【问题讨论】:

    标签: java osgi jndi apache-karaf aries


    【解决方案1】:

    我在尝试在 Weblogic 上部署 Apache Karaf 时遇到了同样的问题。 我们通过 servlet 桥接器使用 karaf - weblogic 中部署了一个战争,它将所有 http 请求桥接到 karaf。

    我在 weblogic 上运行以下应用程序:

    1. app1(使用 JNDI)
    2. app2
    3. karaf-bridge(将请求桥接到 Karaf)

    只要 karaf 启动在 Karaf 中运行的 Aries JNDI 实现,就会将 javax.naming.NamingManager 中的 InitialContextFactoryBuilder 设置为它自己的实现。 NamingManager 持有对初始上下文工厂构建器的静态引用,因此无论其是否在 OSGI 环境中运行,设置此静态引用的任何实现都将成为 JNDI 提供者。

    在我的情况下,当 app1(非 OSGI)尝试创建新的 InitialContext 时,Aries JNDI 尝试使用 BundleContext 解决它并失败。

    我使用一些非常丑陋的技巧解决了这个问题,这些技巧包括从 jre 中提取 javax.naming 包并将其作为包安装在 karaf 中。

    所以你的问题的答案是:我认为问题实际上在于 jre 而不是 OSGI 关于如何管理 JNDI 查找的问题。

    【讨论】:

      【解决方案2】:

      我不确定我是否正确理解了这个问题... JNDI 是一个服务提供者接口,它需要一些底层实现才能运行。您需要做的就是为其配置 OSGI 容器。

      我建议使用 JNDI 所需的所有 jar 创建单个包并导出所有包。然后使用 Dynamic-Import: * 来使用它。它适用于我们的案例(Eclipse RCP 应用程序与用于 EJB 调用的 JBoss 5 JNDI)。

      但是,如果您需要容器内部和外部的 JNDI,并且您不想与 Classloading 作斗争,我建议您将所有 jars 添加到应用程序类路径中。这样,它应该可以在整个应用程序中访问。

      【讨论】:

        【解决方案3】:

        Apache Aries 似乎已经考虑到这一点,并提供了 JRE 初始上下文工厂构建器 (org.apache.aries.jndi.JREInitialContextFactoryBuilder) 的实现,它似乎可以工作。但是,为了使其工作,我必须更改注册 JVM 范围的初始上下文工厂构建器的 Aries 代码。可能有另一种(可能更好)的方式来实现这一点。但这似乎行得通。

        另外,请注意问题并不止于在 NamingManager 中设置 InitialContextFactoryBuilder。 ObjectFactoryBuilder 也出现了同样的问题(在 NamingManager 中再次设置了 JVM 范围)。根据您尝试连接的 JNDI 提供者,您可能还需要更改 Aries JNDI 代码的那部分。例如对于 Tibco EMS JNDI 连接,我必须从 Aries 调整 OSGiObjectFactoryBuilder 的代码以返回 Tibco 特定的 ObjectFactory。这可以使用 Context.OBJECT_FACTORIES 环境值轻松概括。

        我已经为此提出了一个 JIRA - https://issues.apache.org/jira/browse/ARIES-1127

        【讨论】:

          猜你喜欢
          • 2013-05-29
          • 1970-01-01
          • 2012-02-24
          • 2011-03-25
          • 2013-01-04
          • 2012-12-17
          • 2023-03-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多