14

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

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

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

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

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

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

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

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

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)

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

4

3 回答 3

1

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

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

  1. app1(使用 JNDI)
  2. 应用程序2
  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 查找的问题。

于 2013-06-27T13:23:57.913 回答
0

I'm not sure if I understand the problem correctly... JNDI is a Service Provider Interface, and it needs some underlying implementation to run with. All you need to do is to provision it the OSGI container.

I would recommend creating single bundle with all jars needed by JNDI and export all packages. Then use Dynamic-Import: * to use it. It worked in our case (Eclipse RCP application with JBoss 5 JNDI used for EJB calls).

However if you need JNDI inside and outside of the container and you don't want to struggle with Classloading, I would recommend adding all jars to the applications classpath. This way it should be accessible in whole your application.

于 2012-12-22T15:59:32.177 回答
0

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-10-25T02:24:34.113 回答