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

相關問題