欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

java.lang.NoClassDefFoundError錯誤解決辦法

java.lang.NoClassDefFoundError錯誤解決辦法

公司主營業(yè)務:做網(wǎng)站、成都做網(wǎng)站、移動網(wǎng)站開發(fā)等業(yè)務。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)公司推出南岸免費做網(wǎng)站回饋大家。

前言

在日常Java開發(fā)中,我們經(jīng)常碰到java.lang.NoClassDefFoundError這樣的錯誤,需要花費很多時間去找錯誤的原因,具體是哪個類不見了?類明明還在,為什么找不到?而且我們很容易把java.lang.NoClassDefFoundError和java.lang.ClassNotfoundException這兩個錯誤搞混,事實上這兩個錯誤是完全不同的。我們往往花費時間去不斷嘗試一些其他的方法去解決這個問題,而沒有真正去理解這個錯誤的原因。這篇文章就是通過解決NoClassDefFoundError錯誤處理的經(jīng)驗分享來揭開NoClassDefFoundError的一些秘密。NoClassDefFoundError的錯誤并非不能解決或者說很難解決,只是這種錯誤的表現(xiàn)形式很容易迷惑其他的Java開發(fā)者。下面我們來分析下為什么會發(fā)生NoClassDefFoundError這樣的錯誤,以及怎樣去解決這個錯誤。

NoClassDefFoundError錯誤發(fā)生的原因

NoClassDefFoundError錯誤的發(fā)生,是因為Java虛擬機在編譯時能找到合適的類,而在運行時不能找到合適的類導致的錯誤。例如在運行時我們想調用某個類的方法或者訪問這個類的靜態(tài)成員的時候,發(fā)現(xiàn)這個類不可用,此時Java虛擬機就會拋出NoClassDefFoundError錯誤。與ClassNotFoundException的不同在于,這個錯誤發(fā)生只在運行時需要加載對應的類不成功,而不是編譯時發(fā)生。很多Java開發(fā)者很容易在這里把這兩個錯誤搞混。

簡單總結就是,NoClassDefFoundError發(fā)生在編譯時對應的類可用,而運行時在Java的classpath路徑中,對應的類不可用導致的錯誤。發(fā)生NoClassDefFoundError錯誤時,你能看到如下的錯誤日志:

Exception in thread "main" java.lang.NoClassDefFoundError

錯誤的信息很明顯地指明main線程無法找到指定的類,而這個main線程可能時主線程或者其他子線程。如果是主線程發(fā)生錯誤,程序將崩潰或停止,而如果是子線程,則子線程停止,其他線程繼續(xù)運行。

NoClassDefFoundError和ClassNotFoundException區(qū)別

我們經(jīng)常被java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError這兩個錯誤迷惑不清,盡管他們都與Java classpath有關,但是他們完全不同。NoClassDefFoundError發(fā)生在JVM在動態(tài)運行時,根據(jù)你提供的類名,在classpath中找到對應的類進行加載,但當它找不到這個類時,就發(fā)生了java.lang.NoClassDefFoundError的錯誤,而ClassNotFoundException是在編譯的時候在classpath中找不到對應的類而發(fā)生的錯誤。ClassNotFoundException比NoClassDefFoundError容易解決,是因為在編譯時我們就知道錯誤發(fā)生,并且完全是由于環(huán)境的問題導致。而如果你在J2EE的環(huán)境下工作,并且得到NoClassDefFoundError的異常,而且對應的錯誤的類是確實存在的,這說明這個類對于類加載器來說,可能是不可見的。

怎么解決NoClassDefFoundError錯誤

根據(jù)前文,很明顯NoClassDefFoundError的錯誤是因為在運行時類加載器在classpath下找不到需要加載的類,所以我們需要把對應的類加載到classpath中,或者檢查為什么類在classpath中是不可用的,這個發(fā)生可能的原因如下:

  1. 對應的Class在java的classpath中不可用
  2. 你可能用jar命令運行你的程序,但類并沒有在jar文件的manifest文件中的classpath屬性中定義
  3. 可能程序的啟動腳本覆蓋了原來的classpath環(huán)境變量
  4. 因為NoClassDefFoundError是java.lang.LinkageError的一個子類,所以可能由于程序依賴的原生的類庫不可用而導致
  5. 檢查日志文件中是否有java.lang.ExceptionInInitializerError這樣的錯誤,NoClassDefFoundError有可能是由于靜態(tài)初始化失敗導致的
  6. 如果你工作在J2EE的環(huán)境,有多個不同的類加載器,也可能導致NoClassDefFoundError

下面我們看一些當發(fā)生NoClassDefFoundError時,我們該如何解決的樣例。

NoClassDefFoundError解決示例

當發(fā)生由于缺少jar文件,或者jar文件沒有添加到classpath,或者jar的文件名發(fā)生變更會導致java.lang.NoClassDefFoundError的錯誤。

當類不在classpath中時,這種情況很難確切的知道,但如果在程序中打印出System.getproperty(“java.classpath”),可以得到程序實際運行的classpath

運行時明確指定你認為程序能正常運行的 -classpath 參數(shù),如果增加之后程序能正常運行,說明原來程序的classpath被其他人覆蓋了。

NoClassDefFoundError也可能由于類的靜態(tài)初始化模塊錯誤導致,當你的類執(zhí)行一些靜態(tài)初始化模塊操作,如果初始化模塊拋出異常,哪些依賴這個類的其他類會拋出NoClassDefFoundError的錯誤。如果你查看程序日志,會發(fā)現(xiàn)一些java.lang.ExceptionInInitializerError的錯誤日志,ExceptionInInitializerError的錯誤會導致java.lang.NoClassDefFoundError: Could not initialize class,如下面的代碼示例:

/**
 * Java program to demonstrate how failure of static initialization subsequently cause
 * java.lang.NoClassDefFoundError in Java.
 * @author Javin Paul
 */
public class NoClassDefFoundErrorDueToStaticInitFailure {

  public static void main(String args[]){

    List<User> users = new ArrayList<User>(2);

    for(int i=0; i<2; i++){
      try{
      users.add(new User(String.valueOf(i))); //will throw NoClassDefFoundError
      }catch(Throwable t){
        t.printStackTrace();
      }
    }     
  }
}

class User{
  private static String USER_ID = getUserId();

  public User(String id){
    this.USER_ID = id;
  }
  private static String getUserId() {
    throw new RuntimeException("UserId Not found");
  }   
}

Output
java.lang.ExceptionInInitializerError
  at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)
Caused by: java.lang.RuntimeException: UserId Not found
  at testing.User.getUserId(NoClassDefFoundErrorDueToStaticInitFailure.java:41)
  at testing.User.<clinit>(NoClassDefFoundErrorDueToStaticInitFailure.java:35)
  ... 1 more
java.lang.NoClassDefFoundError: Could not initialize class testing.User
  at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)


Read more: http://javarevisited.blogspot.com/2011/06/noclassdeffounderror-exception-in.html#ixzz3dqtbvHDy

由于NoClassDefFoundError是LinkageError的子類,而LinkageError的錯誤在依賴其他的類時會發(fā)生,所以如果你的程序依賴原生的類庫和需要的dll不存在時,有可能出現(xiàn)java.lang.NoClassDefFoundError。這種錯誤也可能拋出java.lang.UnsatisfiedLinkError: no dll in java.library.path Exception Java這樣的異常。解決的辦法是把依賴的類庫和dll跟你的jar包放在一起。

如果你使用Ant構建腳本來生成jar文件和manifest文件,要確保Ant腳本獲取的是正確的classpath值寫入到manifest.mf文件

Jar文件的權限問題也可能導致NoClassDefFoundError,如果你的程序運行在像linux這樣多用戶的操作系統(tǒng)種,你需要把你應用相關的資源文件,如Jar文件,類庫文件,配置文件的權限單獨分配給程序所屬用戶組,如果你使用了多個用戶不同程序共享的jar包時,很容易出現(xiàn)權限問題。比如其他用戶應用所屬權限的jar包你的程序沒有權限訪問,會導致java.lang.NoClassDefFoundError的錯誤。基于XML配置的程序也可能導致NoClassDefFoundError的錯誤。比如大多數(shù)Java的框架像Spring,Struts使用xml配置獲取對應的bean信息,如果你輸入了錯誤的名稱,程序可能會加載其他錯誤的類而導致NoClassDefFoundError異常。我們在使用Spring MVC框架或者Apache Struts框架,在部署War文件或者EAR文件時就經(jīng)常會出現(xiàn)Exception in thread “main” java.lang.NoClassDefFoundError。
在有多個ClassLoader的J2EE的環(huán)境中,很容易出現(xiàn)NoClassDefFoundError的錯誤。由于J2EE沒有指明標準的類加載器,使用的類加載器依賴與不同的容器像Tomcat、WebLogic,WebSphere加載J2EE的不同組件如War包或者EJB-JAR包。關于類加載器的相關知識可以參考這篇文章類加載器的工作原理。

總結來說,類加載器基于三個機制:委托、可見性和單一性,委托機制是指將加載一個類的請求交給父類加載器,如果這個父類加載器不能夠找到或者加載這個類,那么再加載它。可見性的原理是子類的加載器可以看見所有的父類加載器加載的類,而父類加載器看不到子類加載器加載的類。單一性原理是指僅加載一個類一次,這是由委托機制確保子類加載器不會再次加載父類加載器加載過的類。現(xiàn)在假設一個User類在WAR文件和EJB-JAR文件都存在,并且被WAR ClassLoader加載,而WAR ClassLoader是加載EJB-JAR ClassLoader的子ClassLoader。當EJB-JAR中代碼引用這個User類時,加載EJB-JAR所有class的Classloader找不到這個類,因為這個類已經(jīng)被EJB-JAR classloader的子加載器WAR classloader加載。

這會導致的結果就是對User類出現(xiàn)NoClassDefFoundError異常,而如果在兩個JAR包中這個User類都存在,如果你使用equals方法比較兩個類的對象時,會出現(xiàn)ClassCastException的異常,因為兩個不同類加載器加載的類無法進行比較。

有時候會出現(xiàn)Exception in thread “main” java.lang.NoClassDefFoundError: com/sun/tools/javac/Main 這樣的錯誤,這個錯誤說明你的Classpath, PATH 或者 JAVA_HOME沒有安裝配置正確或者JDK的安裝不正確。這個問題的解決辦法時重新安裝你的JDK。

Java在執(zhí)行l(wèi)inking操作的時候,也可能導致NoClassDefFoundError。例如在前面的腳本中,如果在編譯完成之后,我們刪除User的編譯文件,再運行程序,這個時候你就會直接得到NoClassDefFoundError,而錯誤的消息只打印出User類的名稱。

java.lang.NoClassDefFoundError: testing/User
  at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)

現(xiàn)在我們知道要怎樣去面對NoClassDefFoundError異常并解決它了。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

網(wǎng)頁標題:java.lang.NoClassDefFoundError錯誤解決辦法
瀏覽地址:http://chinadenli.net/article10/gehjdo.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)建站公司做網(wǎng)站關鍵詞優(yōu)化微信小程序網(wǎng)站導航

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化