2010-03-29 96 views
3

我试图开发一个web应用程序,这将是launched from a HTTP OSGi service,这个应用程序需要使用其他的OSGi服务(db4o OSGi),因为我需要参考BundleContext。我已经尝试了两种不同的方法来获得在Web应用程序的OSGi的背景:如何从Web应用程序使用OSGi服务?

  1. 商店ActivatorBundleContext一类的Web服务可以导入和使用的静态字段。
  2. 使用FrameworkUtil.getBundle(this.getClass()).getBundleContext()(即thisMainPage,一个Web应用程序的一个实例)。

我认为第一个选项是完全错误的,但无论如何,我在两个选项中遇到了类加载器的问题。在第二个它提出了一个LinkageError

java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/felix/framework/ModuleImpl$ModuleClassLoader) previously initiated loading for a different type with name "com/db4o/ObjectContainer" 

与春分也试过,我有一个类似的错误:

java.lang.LinkageError: loader constraint violation: loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) previously initiated loading for a different type with name "com/db4o/ObjectContainer" 

是引发异常的代码是:

ServiceReference reference = context.getServiceReference(Db4oService.class.getName()); 
Db4oService service = (Db4oService)context.getService(reference); 
database = service.openFile("foo.db"); 

的在最后一行中出现异常,database类为ObjectContainer,如果我将此变量的类型更改为Object,则不会引发异常,但它是没有用作为Object :)

更新:我试图使用其他服务,而不是db4o,他们按预期工作。也许db4o OSGi bundle在加载自己的类时会做一些奇怪的事情,或者我没有正确使用它。如果我使用它从一个非Web包,它也可以工作。

回答

0

为什么不将BundleContext传递给servlet类的构造函数?该类可以安全地存储上下文,因为服务在数据包停止时停止(并且BundleContext变为无效)。

我建议避免在OSGi中使用类加载器,因为a)OSGi框架会执行很多类加载器的魔术,以便将bundle与其他对象分开,并且b)当OSGi可能运行很多问题时并启用了Java 2安全性。这很可能会降低你的包的可重用性。

+0

与我在第一种方法中一样,将上下文存储在静态字段中将会不一样吗? 关于玩类加载器,是的,我认为是一样的。谢谢。 – 2010-04-05 08:47:30

+0

是的,它基本上是一样的,只是另一种方法。您应该只将束上下文传递给来自同一束的对象。 – akr 2010-04-05 12:06:07

0

我不是100%肯定这会帮助你,但你可以尝试尝试访问其他包中的类之前设置线程的上下文类加载器:

Thread currentThread = Thread.currentThread(); 
ClassLoader origLoader = currentThread.getContextClassLoader(); 

currentThread.setContextClassLoader (Db4oService.class.getClassLoader()); 

ServiceReference reference = context.getServiceReference(Db4oService.class.getName()); 
Db4oService service = (Db4oService)context.getService(reference); 
database = service.openFile("foo.db"); 

currentThread.setContextClassLoader (origLoader); 

它看起来像OSGi是检测来自另一个包(Db4oService)的已加载的类将由此类加载器加载。

+0

完整的例子,我想你的解决方案,但我仍然有同样的问题。谢谢。 – 2010-04-05 08:54:31

0

使用环境felix-server和jetty运行webservices,您可以轻松使用任何webservices中的任何OSGi服务。

首先,您必须在您的webservice中注入ServletContext,以便通过调用servletContext.getAttribute(“osgi-bundlecontext”)来访问OSGi上下文。结果是您的OSGi包上下文。

请找到http://blog.meyerdaniel.ch/2012/08/accessing-osgi-services-from-servlets.html

相关问题