2012-11-10 49 views
1

又一個愚蠢的問題。我相信這很容易,但是這已經花了我很多時間,我不明白它的工作原理;(無法添加jar到OSGi包

我有一個書面的工作原型,用於對服務器進行其他調用。我使用的是「jersey-client-1.14.jar」。將它添加到eclipse項目類路徑中效果相當不錯。

現在我試圖在OSGi包中做同樣的事情。

  1. 我在OSGi包項目創造了/ lib文件夾。
  2. 添加了球衣,客戶1.14.jar該文件夾中。
  3. 在類路徑的MANIFEST.MF中添加jar:Bundle-ClassPath:。,lib/jersey-client-1.14.jar
  4. 檢查它是否也正確添加到項目類路徑中。
  5. 在Eclipse工作區中我沒有編譯錯誤。

在運行時,我遇到了使用Client.create()創建球衣客戶端時發現classdef沒有發現異常的現象;

 
!ENTRY org.eclipse.equinox.event 4 0 2012-11-08 23:14:43.975 

!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=openhab/command/Hue_Bulb_2] to handler [email protected] 

!STACK 0 

java.lang.NoClassDefFoundError: Could not initialize class com.sun.jersey.spi.service.ServiceFinder 

at com.sun.jersey.api.client.Client.init(Client.java:213) 

at com.sun.jersey.api.client.Client.access$000(Client.java:118) 

at com.sun.jersey.api.client.Client$1.f(Client.java:191) 

at com.sun.jersey.api.client.Client$1.f(Client.java:187) 

at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:193) 

at com.sun.jersey.api.client.Client.(Client.java:187) 

at com.sun.jersey.api.client.Client.(Client.java:159) 

at com.sun.jersey.api.client.Client.create(Client.java:669) 

at org.openhab.binding.hue.internal.bridge.HueBridge.getSettingsJson(HueBridge.java:64) 

at org.openhab.binding.hue.internal.bridge.HueBridge.pairBridgeIfNecessary(HueBridge.java:19) 

at org.openhab.binding.hue.internal.HueBinding.receiveCommand(HueBinding.java:37) 

at org.openhab.core.events.AbstractEventSubscriber.handleEvent(AbstractEventSubscriber.java:62) 

at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:197) 

at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) 

at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) 

at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) 

at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) 

at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) 

at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) 

at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) 

at org.openhab.core.internal.events.EventPublisherImpl.sendCommand(EventPublisherImpl.java:76) 

at org.openhab.ui.webapp.internal.servlet.CmdServlet.service(CmdServlet.java:115) 

at org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61) 

at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:128) 

at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:60) 

at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) 

at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:598) 

at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:486) 

at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231) 

at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065) 

at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:413) 

at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192) 

at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999) 

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117) 

at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250) 

at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149) 

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111) 

at org.eclipse.jetty.server.Server.handle(Server.java:350) 

at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454) 

at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:890) 

at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:944) 

at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:630) 

at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230) 

at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77) 

at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:606) 

at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46) 

at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603) 

at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538) 

at java.lang.Thread.run(Thread.java:680) 

23:14:43.992 ERROR OSGi[:98] - Exception while dispatching event org.osgi.service.event.Event [topic=openhab/command/Hue_Bulb_2] to handler [email protected] 

java.lang.NoClassDefFoundError: Could not initialize class com.sun.jersey.spi.service.ServiceFinder 

at com.sun.jersey.api.client.Client.init(Client.java:213) 

at com.sun.jersey.api.client.Client.access$000(Client.java:118) 

at com.sun.jersey.api.client.Client$1.f(Client.java:191) 

at com.sun.jersey.api.client.Client$1.f(Client.java:187) 

at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:193) 

at com.sun.jersey.api.client.Client.(Client.java:187) 

at com.sun.jersey.api.client.Client.(Client.java:159) 

at com.sun.jersey.api.client.Client.create(Client.java:669) 

at org.openhab.binding.hue.internal.bridge.HueBridge.getSettingsJson(HueBridge.java:64) 

at org.openhab.binding.hue.internal.bridge.HueBridge.pairBridgeIfNecessary(HueBridge.java:19) 

at org.openhab.binding.hue.internal.HueBinding.receiveCommand(HueBinding.java:37) 
+0

你能告訴我們你的清單文件嗎?我建議您使用Maven-Bundle-Plugin來幫助您構建清單文件,而不是手動編輯它。 – wulfgarpro

回答

3

您還需要將jersey-core添加到bundle的類路徑中,因爲jersey-client將它作爲依賴項。

如果需要,您可能需要添加其他依賴項。這個過程是相當容易的,如果不愉快:

  1. 添加一個罐子
  2. 運行應用程序
  3. 看到什麼類沒有找到,找到罐子在那裏階級的生活,把它添加到包類路徑,走回到2

但有一兩件事:新澤西罐子OSGi的準備,所以你可能也只是增加球衣,client.jar中和球衣-core.jar添加到您的taget平臺和導入所需的軟件包。

+0

我「解決」通過將以下jar文件到目標平臺的問題: 球衣,客戶1.15.jar 球衣核心 - 1.15.jar JSR311的API-1.0.jar ,讓我將它們添加爲我的包中的依賴項...感謝提示。 – Shingoo

0

先生,在eclipse中你已經添加了不同的包。 com.sun.jersey.spi.service.ServiceFinder。開始你的服務,你必須開始其他服務。你綁定的是依賴的。 就像我有一個jar,它取決於rxtxcomm_api-2.1.7.jar。 我不得不初始化它,或者你可以說明它。在我服務之前。請檢查一下。

+0

這不是我想要做的。我不希望澤西運行作爲一個單獨的捆綁,但作爲一個jar文件在我自己的捆綁... – Shingoo

+0

hmm ..同樣在這裏..我的rstxconn jar實際上是一個單獨的捆綁。但在我的主要文件。 ia hd增加了它的路徑。這意味着當我開始我的服務時,它應該用於我的罐子。 – xdeepakv

0

OSGi中嵌入罐是一種糟糕的風格。一般來說,只有在沒有其他方式時才應該這樣做。嵌入罐很容易導致類路徑問題,因爲軟件包可能來自不同的捆綁包。爲什麼要嵌入罐子有什麼特別的原因嗎? 自1.2版以來,Jersey完全支持OSGi。請參閱documentation for examples如何使用它。

+0

這是corect,但我仍然想知道如何解決問題...只是爲了瞭解我做錯了什麼...只是爲了教育。 ;) – Shingoo

+0

我認爲彼得的評論應該有所幫助。如果你看一下Client的代碼,你會發現ServiceFinder甚至在ContextClassLoader中使用了一些classloader魔法。這些是lib不完全符合OSGi的情況。調整這些案件的進口並不容易。因此,依靠預先打包的libs版本始終是更好的選擇。 –

0

大多數OSGi容器都帶有一個JAX-RS開箱即用的工具 - 可以是澤西島或什麼都不是。例如,我們使用Apache ServiceMix,它可以方便地提供Apache CXF。

  • 您使用什麼容器?
  • 你是否真的必須將Jersey與你的應用程序捆綁在一起?

如果你需要捆綁澤西出於任何原因,你能否提供一個清單文件的例子。

  • 你有沒有考慮過使用Maven-Bundle-Plugin?
+0

感謝您的幫助。我想過Maven,但我只是想了解發生了什麼,爲了教育目的。 ;) – Shingoo

1

看你的二次查詢,我覺得你只是想知道這是怎麼回事:-)

的OSGi 圍欄 JAR文件創建的模塊。默認情況下,圍欄是不可見的,bundle外的任何類(jar)都不可見(能夠從類加載類)到內部的類,而外部人看不到內部的任何東西。優勢應該是顯而易見的:你可以改變內心的喜悅,因爲在外面什麼都不知道。

但是,在現實生活中,您需要在圍欄中留出一些洞來與其他人合作。在你的情況下,一個包會嘗試加載com.sun.jersey.spi.service.ServiceFinder,但它會跑到圍欄中,因爲沒有合適的洞。

OSGi中的「洞」是包,這些是共享的原子。您在清單中列出這些軟件包。 Import-Package標題指示您需要從外部世界看到的包,並且Export-Package標頭定義包對其他包可見的包(以及在什麼版本下)。

顯然你不想手動計算導入,因爲這些已經在你的類文件中,因此有一個工具bnd(我是作者),可以從maven,ant,gradle等使用。它需要一個配方,並使用適當的元數據計算結果包。該工具得到了bndtools Eclipse插件的廣泛支持,這是一個瞭解OSGi和這些問題的更好的環境。