OSGI JNDI是否允许与来自非OSGI代码的JNDI调用共存



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知道"?

我自己在ApacheKaraf 2.3.0(使用ApacheAries JNDI 1.0.0)中尝试过这一点,但似乎不起作用,因为ApacheAries需要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)

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

我在Weblogic上部署ApacheKaraf时遇到了同样的问题。我们通过servlet桥使用karaf——在weblogic中部署了一个war,它将所有http请求桥接到karaf。

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

  1. app1(使用JNDI)
  2. app2
  3. 卡拉夫大桥

一旦karaf启动,在karaf内部运行的Aries JNDI实现就会将javax.naming.NamingManager内部的InitialContextFactoryBuilder设置为自己的实现。NamingManager持有对初始上下文工厂生成器的静态引用,因此无论哪个实现,无论其是否在OSGI环境中运行,设置该静态引用的都将成为JNDI提供程序。

在我的案例中,当app1(非OSGI)尝试执行新的InitialContext时,Aries JNDI尝试使用BundleContext解决它,但失败了。

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

因此,您的问题的答案是:我认为问题真正在于jre,而不是OSGI如何管理JNDI查找。

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

我建议使用JNDI所需的所有jar创建单个捆绑包,并导出所有包。然后使用DynamicImport:*来使用它。它在我们的案例中起作用(带有JBoss5JNDI的Eclipse RCP应用程序用于EJB调用)。

但是,如果您在容器内外都需要JNDI,并且不想在Classloading方面遇到困难,我建议您将所有jar添加到应用程序类路径中。这样,它应该可以在整个应用程序中访问。

Apache Aries似乎已经考虑到了这一点,并提供了JRE初始上下文工厂生成器(org.Apache.Aries.jndi.JREInitialContextFactoryBuilder)的实现,该实现似乎有效。然而,为了实现这一点,我不得不更改Aries代码,该代码注册JVM范围的初始上下文工厂构建器。实现这一点可能还有另一种(可能更好的)方式。但这似乎奏效了。

此外,请注意,问题并没有停止在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

相关内容

  • 没有找到相关文章

最新更新