2017-10-17 268 views
2

我正在使用karaf 4.0.5和osgi進行項目工作。我們有客戶端代碼來調用REST API,它需要加載3個「* .properties」文件。我有一個客戶端jar,我用它來調用服務器端類和方法(包含我無法更新的代碼)。所需的屬性文件存在於提供的客戶端jar中,但他們的代碼仍然未找到並加載它們。將資源文件添加到karaf類路徑

在調試我的pax考試時,我發現下面可能的原因是它沒有從jar中加載資源文件。

  1. 代碼載入的文件似乎試圖僅從捆綁類加載器加載資源,並
  2. 它稱之爲「getResource()」的方法,而不是「getResourceAsStream()」的方法。

另外,我嘗試添加的資源目錄我的文件系統上,並附加與目錄所在位置的類路徑,如:

-cp .;C:/Users/abcUser/Desktop/resourceFolder/;

(Windows 7中,類路徑條目在使用eclipse中的junit 4+執行pax考試時添加爲VM參數) - >這不起作用,它仍然無法找到這些文件。 我有什麼其他選項,所以Bundle Classloader可以找到這些文件?

注意:我們已經有一堆其他* .cfg文件,其內容使用藍圖加載到bean中並註冊到容器中,但這不是我在這裏需要做的。在運行時期間,這些文件應該可用於BundleClassloader,並且應該由「getResource()」方法檢索。

更新:繼接受答案的下面部分後,應用程序已成功加載屬性文件。

另一件要檢查的問題是客戶端代碼在嘗試加載這些資源時是否實際上使用了bundle classloader。在某些情況下,代碼試圖通過使用線程上下文類加載器來實現聰明,在調用客戶端代碼之前,需要對其進行適當設置。

來自客戶端jar的代碼完全按照猜測:資源加載發生在使用Thread.currentThread().getContextClassLoader()。我可以將ContextLoader設置爲CustomAbstractProcessor的類加載器,它現在從該包的類路徑加載屬性文件!

ClassLoader previousCL = Thread.currentThread().getContextClassLoader(); 
Thread.currentThread().setContextClassLoader(CustomAbstractProcessor.class.getClassLoader()); 
try { 
    //REST call to server using classes and methods from provided client jar. 
} 
finally { 
    Thread.currentThread().setContextClassLoader(previousCL); 
} 

回答

1

我已經給出我使用來調用服務器側的類和方法(含有的代碼,我無法更新)客戶端罐子。所需的屬性文件存在於提供的客戶端jar中,但他們的代碼仍然未找到並加載它們。

如果該客戶端jar運行作爲一個OSGi包,那麼它應該能夠找到使用自己的類加載器(捆綁類加載器)資源,如果(且僅當)的資源在bundle的類路徑。

OSGi包的默認類路徑是.,即包的根。這可以使用清單標頭Bundle-ClassPath覆蓋,並用於捆綁中的一個或多個位置。

  • 一種可能性是客戶端軟件包具有不同的類路徑集,而屬性文件不在其上。
  • 另一種可能性是屬性文件位於類路徑中,但是位置與期望的不符。代碼尋找foo.properties和文件是`/props/foo.properties'

它調用getResource()方法,而不是getResourceAsStream()方法。

getResourceAsStream()只是一個無效安全版本getResource().openStream()

我還有其他的選擇,所以Bundle Classloader會找到這些文件嗎?

要檢查的另一件事是,當試圖加載這些資源時客戶端代碼是否實際上使用了bundle classloader。在某些情況下,代碼試圖通過使用線程上下文類加載器來實現聰明,在調用客戶端代碼之前,需要對其進行適當設置。

+0

添加了對我的原始文章進行更新的解決方案。按照建議設置'ContextClassLoader'就有訣竅了! –