運行JSP報表程序頁面出現java.lang.UnsatisfiedLinkError: CC錯誤有如下幾種緣由和處理方法:git
一、請查看控制檯的錯誤信息
a:若是控制檯的消息是相似web
java.lang.UnsatisfiedLinkError: no MRChkLib in java.library.path,Error loading library MRChkLibbootstrap
這樣的錯誤信息,那麼是由於MRChkLib.dll沒有拷貝到windows的System32目錄下. (MRChkLib.dll是加密鎖的JAVA接口文件,文件在報表安裝目錄DogDriver/JavaAPI下能夠找到) 而且要注意PATH環境變量中要包含System32目錄。(若是服務器操做系統是Linux,那麼使用報表安裝目錄DogDriver/JavaAPI 下的libMRChkLib.so文件,將libMRChkLib.so複製到WebServer的啓動bin目錄。若是在這個目錄下仍然出現can not load library錯誤,請設置系統環境變量LD_LIBRARY_PATH的值爲libMRChkLib.so所在的目錄。
例如:若是libMRChkLib.so在/somedir目錄下,則 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/somedir)windows
b:若是控制檯的消息是相似服務器
java.lang.unsatisfiedLinkError :native libery c:/winnt/system32/mrchklib.dll already loaded in another classLoader error loading mrchklib.dllapp
這樣的錯誤信息,那麼是由於WebAPP在從新被啓動以後,沒法再次加載動態庫形成的,這是java的約束,Java不容許一個實例加載屢次動態 庫.能夠這樣解決,將mr.jar拷貝到WebServer的lib目錄,刪除/WEB-INF/lib目錄下的mr.jar,而後從新啓動 webserver。eclipse
二、若是一個webserver上有多個報表應用,請將/WEB-INF/lib/mr.jar移動到WebServer的lib目錄下,確保每個Web應用程序目錄下都沒有mr.jar,而只有WebServer的lib目錄下有該文件,重啓webserver.函數
三、一個Webserver上只能有一個mr.jar文件,刪掉多餘的mr*.jar文件,而後清除webserver臨時文件,從新啓動webserver。
===================================================================================
最近項目中用到了jni,因而安裝了eclipse的cdt和MinGW來用,之前沒怎麼動過C語言,網上找了下教程,卻是挺容易的,一路弄下來也沒提示什麼錯誤,可是在最後調用本地方法時卻遇到了大麻煩,老是提示找不到方法。即便一個簡單的HelloWorld,也是同樣
Exception in thread "main" java.lang.UnsatisfiedLinkError: HelloWorld.print()V
奇怪了,loadLibrary()沒有問題,怎麼會找不到方法呢?用dll export viewer察看,導出的方法爲
函數名 地址 偏移量
Java_HelloWorld_print@8 0x67741250 0x00001250
實在沒辦法了,只好安裝龐大的visual studio從新來編譯,調用成功了!
再次用dll export viewer查看,發現函數名的前面多了一條下劃線
函數名 地址 偏移量
_Java_HelloWorld_print@8 0x67741250 0x00001250
看來是給MinGW少傳了某個參數,通過網上查閱資料,終於找到一個解決方案:給MinGW的ld命令指定一個參數--kill-at便可
gcc -Wl, --kill-at -shared -o jnihello.dll HelloWorld.c
再次用dll export viewer查看,發現導出的函數名稱變爲
函數名 地址 偏移量
Java_HelloWorld_print 0x67741250 0x00001250
--kill-at指令去掉了函數名稱後綴的@,並無像msvc那樣添加前綴的下劃線
========================================================================
現象: java.lang.UnsatisfiedLinkError: Native Library xxx.dll already loaded in another classloader at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1551) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1511) at java.lang.Runtime.loadLibrary0(Runtime.java:788) at java.lang.System.loadLibrary(System.java:834) 分析: 這種錯誤在咱們使用熱啓動方式發佈某個使用了JNI技術的Web應用時,並將調用年native方法的jar包獨立部署在該應用下面,當咱們的Web應用 有了更新之後,在調用到該jar包封裝的native方法時,會拋出該錯誤。(以上OS爲Windows,如果Linux或Unix,應該是xxx.so 報錯) 這是由於Web服務器已經在第一次加載該應用時,已經load了該dll,當該應用被再次熱啓動時,該dll將從新被加載,因而報錯。 解決方案: 1、將含有JNI調用的jar包部署在Web服務器的公用lib庫中。Web應用再發布時能夠不用加載; 2、jar包部署不變,在該Web中實現一個listener,監聽是否第一次啓動,若不是第一次啓動,屏蔽掉該jar包所含dll的加載。
========================================================================
類裝入問題:UnsatisfiedLinkError |
做者:Simon Burns 來源:IBM 整理日期:2007-6-3 |
UnsatisfiedLinkError
在把本機調用連接到對應的本機定義時,類裝入器扮演着重要角色。若是程序試圖裝入一個不存在或者放錯的本機庫時,在連接階段的解析過程會發生 UnsatisfiedLinkError 。JVM 規範指定 UnsatisfiedLinkError 是:
對於聲明爲
native 的方法,若是 Java 虛擬機找不到和它對應的本機語言定義,就會拋出該異常。
當調用本機方法時,類裝入器會嘗試裝入定義了該方法的本機庫。若是找不到這個庫,就會拋出這個錯誤。
清單 6 演示了拋出 UnsatisfiedLinkError 的測試用例 :
清單 6. UnsatisfiedLinkError.
java
public class UnsatisfiedLinkErrorTest { public native void call_A_Native_Method(); static { System.loadLibrary("myNativeLibrary"); } public static void main(String[] args) { new UnsatisfiedLinkErrorTest().call_A_Native_Method(); } } |
這段代碼調用本機方法 call_A_Native_Method() ,該方法是在本機庫 myNativeLibrary 中定義的。由於這個庫不存在,因此在程序運行時會發生如下錯誤:
The java class could not be loaded. java.lang.UnsatisfiedLinkError: Cant find library myNativeLibrary (myNativeLibrary.dll) in sun.boot.library.path or java.library.path sun.boot.library.path=D:/sdk/jre/bin java.library.path= D:/sdk/jre/bin at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2147) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:2006) at java.lang.Runtime.loadLibrary0(Runtime.java:824) at java.lang.System.loadLibrary(System.java:908) at UnsatisfiedLinkErrorTest.<clinit>(UnsatisfiedLinkErrorTest.java:6) |
本機庫的裝入由調用 System.loadLibrary() 方法的類的類裝入器啓動 —— 在清單 6 中,就是 UnsatisfiedLinkErrorTest 的類裝入器。根據使用的類裝入器,會搜索不一樣的位置:
- 對於由 bootstrap 類裝入器裝入的類,搜索
sun.boot.library.path 。
- 對於由擴展類裝入器裝入的類,先搜索
java.ext.dirs ,而後是 sun.boot.library.path ,而後是 java.library.path 。
- 對於由系統類裝入器裝入的類,搜索
sun.boot.library.path ,而後是 java.library.path 。
在清單 6 中,UnsatisfiedLinkErrorTest 類是由系統類裝入器裝入的。要裝入所引用的本機庫,這個類裝入器先查找 sun.boot.library.path ,而後查找 java.library.path 。由於在兩個位置中都沒有須要的庫,因此類裝入器拋出 UnsatisfiedLinkageError 。
|
==========================================================================
java.lang.UnsatisfiedLinkError 出現這種錯誤的緣由是通常是java虛擬機找不到聲明爲native方法的本地語言定義時,出現的錯誤。在個人理解過程當中我通常都認爲是因爲導入dll或 者導入lib文件不正確致使的。有些須要靜態導入就沒有問題(即在前面加static來導入lib文件),若是是不加static導入也就是動態導入的時 候,那麼須要添加catch的拋出異常來解決,如 try{ System.loadLibrary("vtkCommonJava"); System.loadLibrary("vtkFilteringJava"); System.loadLibrary("vtkIOJava"); System.loadLibrary("vtkImagingJava"); System.loadLibrary("vtkGraphicsJava"); System.loadLibrary("vtkRenderingJava"); }catch(Throwable e) { System.out.println("The load problem"); } 這種方式來判斷,或者直接在類前面添加 static{ System.loadLibrary("vtkCommonJava"); System.loadLibrary("vtkFilteringJava"); System.loadLibrary("vtkIOJava"); System.loadLibrary("vtkImagingJava"); System.loadLibrary("vtkGraphicsJava"); System.loadLibrary("vtkRenderingJava");
}
================================================================================
關於java.lang.UnsatisfiedLinkError(JNI) |
|
|
目標:把pbp1.0的java包和native移到GEM中,並使GEM在新的虛擬機上正常運行
背景:GEM(1)有一堆java包和native函數,pbp1.0是虛擬機和JAVA基本包,要將pbp1.0的虛擬機移走只用它的JAVA基本包和native函數。
問題:在將GEM和pbp1.0的native函數生成一個動態庫後在程序裏System.loadLibrary()沒法加載,報java.lang.UnsatisfiedLinkError
解決過程:
1,理論
咱們知道,JAVA調用native函數時,必須經過System.loadLibrary()或System.load將其native函數所在動態庫 加載到虛擬機。並在運行時指明-Djava.library.path或-Dsun.boot.library.path,將其指向包含有native函 數的動態庫所在位置。
2,實施
我按這個步驟操做完成後就是沒法加載我生成的動態庫libgem.so,這個庫用到的其餘動態庫包括:rt,pthread,freetype,dl, directfb,而directfb用到的動態庫有rt,dl,pthread,freetype,jpeg,png,這些庫除了directfb要生 成外其他都在/lib目錄下存在。
3,思路
先寫了一個Hello的測試用例。發如今native裏所使用到其餘動態庫時,不管是否存在於相關目錄,仍然沒法加載。而後通過修改編譯選項,把所使用到的動態庫連動態鏈接進目標庫,以下:
$(GCC) -fPIC -shared -o libdirectfb.so ... -lpng -ljpeg -lpthread -lrt -ldl, -lfreetype
通過這麼一個修改後,directfb能夠加載。
這也說明System.loadLibrary()所加載的動態庫所引用的全部符號都要能找到。若是有一個沒法找到將沒法加載。能夠寫一個空的main ()函數,對你的動態庫進行鏈接,若是動態庫裏所引用的符號在指定的動態庫和自己找到不到則沒法編譯經過,那麼這個動態庫也確定加載不了。
4,問題解決
按照這個思路,對libgem.so的編譯Makefile作相應修改後,問題解決!並在LD_LIBRARY_PATH加入動態庫所在目錄。
(1) MHP (Multimedia Home Platform) was developed by the DVB Project as the world's first open standard for interactive television. It is a Java-based environment which defines a generic interface between interactive digital applications and the terminals on which those applications execute. MHP was designed to run on DVB platforms but there was a demand to extend the interoperability it offers to other digital television platforms. This demand gave rise to GEM, or Globally Executable MHP, a framework which allows other organisations to define specifications based on MHP.
|
|
==================================================================================== 另外,還多是dll自己的問題,使用release版的,而不要用debug版的 |
=============================================================================