2013-07-29 68 views
0

背景:在karaf中,我有兩個使用不同版本的Jersey(1.17和2.0)的功能。在Karaf OSGI中,我得到了ClassNotFoundException,它是拋出異常的包中的類

它們彼此分開,沒有導入它們的捆綁包。

Jersey 1.17和2.0之間的軟件包名稱已更改(com.sun.jersey與org.glassfish.jersey)。

無論如何,使用球衣1.17的捆綁工作正常。

爲了使2.0工作(大概),我讀了一個地方,我可以指定我的META-INF目錄中名爲「services」的目錄中的消息讀取器的FQN。 (按照http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider

,看起來像這樣:

META-INF /服務/ javax.ws.rs.ext.MessageBodyReader:

org.glassfish.jersey.message.internal.XmlRootObjectJaxbProvider.App 
org.glassfish.jersey.message.internal.SourceProvider.StreamSourceReader 
org.glassfish.jersey.message.internal.SourceProvider.SaxSourceReader 
org.glassfish.jersey.message.internal.SourceProvider.DomSourceReader 
org.glassfish.jersey.message.internal.XmlRootObjectJaxbProvider.Text 
org.glassfish.jersey.message.internal.XmlRootObjectJaxbProvider.General 

這似乎是工作,因爲我的組織.glassfish.jersey.core.jersey-common 2.0包嘗試加載第一個類。但是它會拋出一個ClassNotFoundException。

2013-07-29 14:36:45,334 | WARN | Executor: 2  | OsgiRegistry      | egistry$BundleSpiProvidersLoader 222 | 207 - org.glassfish.jersey.core.jersey-common - 2.0.0 | [] | Exception caught while loading SPI providers. 
java.lang.ClassNotFoundException: org.glassfish.jersey.message.internal.XmlRootObjectJaxbProvider.App 
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)[osgi-3.8.0.v20120529-1548.jar:] 
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)[osgi-3.8.0.v20120529-1548.jar:] 
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)[osgi-3.8.0.v20120529-1548.jar:] 
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)[osgi-3.8.0.v20120529-1548.jar:] 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)[:1.7.0_21] 
    at org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:340)[osgi-3.8.0.v20120529-1548.jar:] 
    at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)[osgi-3.8.0.v20120529-1548.jar:] 
    at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1212)[osgi-3.8.0.v20120529-1548.jar:] 
    at org.glassfish.jersey.internal.OsgiRegistry$BundleSpiProvidersLoader.call(OsgiRegistry.java:217)[207:org.glassfish.jersey.core.jersey-common:2.0.0] 
    at org.glassfish.jersey.internal.OsgiRegistry$BundleSpiProvidersLoader.call(OsgiRegistry.java:189)[207:org.glassfish.jersey.core.jersey-common:2.0.0] 
    at org.glassfish.jersey.internal.OsgiRegistry.locateAllProviders(OsgiRegistry.java:468)[207:org.glassfish.jersey.core.jersey-common:2.0.0] 

注意這是束207的球衣,共同2.0

發生,如果我跑

[email protected]> osgi:find-class XmlRootObjectJaxbProvider 

jersey-core-common (207) 
org/glassfish/jersey/message/internal/XmlRootObjectJaxbProvider$App.class 
org/glassfish/jersey/message/internal/XmlRootObjectJaxbProvider$General.class 
org/glassfish/jersey/message/internal/XmlRootObjectJaxbProvider$Text.class 
org/glassfish/jersey/message/internal/XmlRootObjectJaxbProvider.class 

類是在那裏,在同一個包!它無法在自己的包中找到一個類。

這對我來說沒有意義,除非glassfish以某種方式使用其他類加載器。任何人都可以對此有所瞭解嗎?

謝謝。

更新 我發現了這個錯誤:

https://java.net/jira/browse/GLASSFISH-16970

這使我這個wiki對此事:

https://wikis.oracle.com/display/GlassFish/JdkSpiOsgi

我不明白我怎麼能實現他們的工作環境不會破壞球衣核心通用的罐子。

回答

2

哦,有什麼糾結的時候,我們希望這種:-(完全混亂是由Java的缺乏服務註冊表造成避免使用服務,我們織網。

我想你的問題是,球衣嘗試從加載因爲它找到了該服務目錄中的服務目錄,因爲你沒有這些類,所以Jersey正確無誤。

最初的解決方案是將這些文件放在球衣包中的services目錄中,要求你打開該捆綁。如果球衣包出口實施包(模塊化的詛咒,但通常在不瞭解OSGi的代碼中完成),即使您不直接使用它們,也可以將這些包導入到包中。

另一種替代方案,我沒有檢查出來,是使用OSGi hack:fragments。您可以對包含services目錄的運動衫包進行片段化。但是,不知道這是否有效。

最後但並非最不重要的一點,你可以在自己的私人包中包含球衣代碼。用bnd,這很容易做到。

+0

我會先與最後一條建議一起去嘗試解決這個問題(包括WAB中的所有內容)。之後,我會嘗試再次從戰爭/廢物中分離出來,然後再導入所需的東西。大多數免費使用的「服務」不提供OSGi服務是可惜的,但是,您可以不要自己做任何事情。 ;) –

+0

@Achim:是的,它表示沒有更多的包提供OSGi服務。然而,看到maven中心的捆綁數量增加的速度是非常有希望的。 –

相關問題