2009-12-13 31 views
8

我使用的是最近發佈的Glassfish的第三版,同時使用本地庫的GlassFish會間歇性地抱怨Glassfish的本機庫加載文件(.dll,的.so)

glassfish SEVERE: java.lang.UnsatisfiedLinkError: 
Native Library already loaded in another classloader

程序加載本機庫在此前發佈的GlassFish(V2。 2)只是將.dll文件放在GLASSFISH_HOME \ lib中。現在我不知道v3中是否有這樣一個魔法文件夾,並且如果有的話。我也檢查了管理員屏幕,並且我認爲有兩個變量與我的問題有關:本地庫路徑前綴和本機庫路徑後綴。我一直在搜索互聯網,找到他們所做的事情以及我應該如何使用它們的充分描述,但顯然沒有人喜歡談論它們。

回答

3

第一件事:一個給定的本地類只能加載到一個類加載器。第二件事:servlet容器中的每個Web應用程序都有自己的類加載器。

第三件事:你必須在編碼的本地代碼,允許它的類進行垃圾回收非常小心。

結果:當您載入本地代碼到一個web應用程序,你如果您嘗試卸載和重裝它有可能得到這些錯誤。

我,在一定程度上,跳過這個主題很簡單變化:簡單地加載兩個不同的webapps具有相同的本地類。

有些人喜歡在系統類加載器中加載本機代碼以避免出現此問題。

4
java.lang.UnsatisfiedLinkError: Native Library already loaded in another classloader 

一個本地庫只能在JVM一旦加載,只要你加載調用類的新版本(其中System.loadLibrary(String)呼叫駐留的類),你會得到錯誤信息上重新部署。更多關於下面的內容。

的程序加載在以前的GlassFish版本(V2.2)本機庫是簡單地把.dll文件中GLASSFISH_HOME\lib

好吧,其實這只是故事的第一部分。要加載本地庫,您當然可以將它放在庫路徑上以從Java代碼加載它。要做到這一點,慣例是包括靜態初始化程序是這樣的:

class FooWrapper { 
    static { 
     System.loadLibrary("foo"); 
    } 

    native void doFoo(); 
    } 
} 

假設你有一個Web應用程序時,最好的做法是不要將本機庫或它們的JNI接口WEB-INF/libWEB-INF/classes下如上所述,在重新加載應用程序時避免出現問題。換句話說,調用System.loadLibrary(String)的類應該由不受重載Web應用程序本身影響的類加載器加載。

所以我的問題是:你把這個代碼放在哪裏?

PS:另一個選擇是檢查dll在加載之前是否已經可用,但我不會這樣做。