java.lang.NoClassDefFoundError:如何解決–第2部分

本文是我們的NoClassDefFoundError故障排除系列的第2部分。 看一下第1部分 。 它將重點介紹最簡單的NoClassDefFoundError問題類型。 本文對于Java初學者來說是理想的選擇,我強烈建議您自己編譯并運行示例Java程序。

今后將使用以下書寫格式,并為您提供:
–問題案例的描述和NoClassDefFoundError的類型
–示例Java程序“模擬”問題情況 – ClassLoader鏈視圖 –建議和解決策略

NoClassDefFoundError問題案例1 –缺少JAR文件

我們將介紹的第一個問題案例與Java程序包裝和/或類路徑問題有關。 典型的Java程序可以包含一個或多個在編譯時創建的JAR文件。 當您忘記添加包含Java或Java EE應用程序引用的Java類的JAR文件時,通常會觀察到NoClassDefFoundError。

一旦您分析了Java異常并缺少Java類名,通常就不難解決這種類型的問題。

示例Java程序

以下簡單的Java程序按以下方式拆分:
–主Java程序NoClassDefFoundErrorSimulator
–調用者Java類CallerClassA –引用Java類ReferencingClassA –用于ClassLoader和日志記錄相關設施的util類JavaEETrainingUtil

這個程序很簡單,它試圖創建一個新實例并執行一個Java類CallerClassA的方法,該方法引用了ReferencingClassA類。 它將演示一個簡單的類路徑問題如何觸發NoClassDefFoundError。 該程序還在類加載時顯示當前類加載器鏈的詳細信息,以幫助您跟蹤此過程。 當處理更大的類加載器鏈時,這對于將來和更復雜的問題案例特別有用。

package org.ph.javaee.training1;import org.ph.javaee.training.util.JavaEETrainingUtil;/*** NoClassDefFoundErrorTraining1* @author Pierre-Hugues Charbonneau**/
public class NoClassDefFoundErrorSimulator {/*** @param args*/public static void main(String[] args) {System.out.println("java.lang.NoClassDefFoundError Simulator - Training 1");System.out.println("Author: Pierre-Hugues Charbonneau");System.out.println("http://javaeesupportpatterns.blogspot.com");// Print current Classloader contextSystem.out.println("\nCurrent ClassLoader chain: "+JavaEETrainingUtil.getCurrentClassloaderDetail());// 1. Create a new instance of CallerClassACallerClassA caller = new CallerClassA();// 2. Execute method of the callercaller.doSomething();System.out.println("done!");}
}
package org.ph.javaee.training1;import org.ph.javaee.training.util.JavaEETrainingUtil;/*** CallerClassA* @author Pierre-Hugues Charbonneau**/
public class CallerClassA {private final static String CLAZZ = CallerClassA.class.getName();static {System.out.println("Classloading of "+CLAZZ+" in progress..."+JavaEETrainingUtil.getCurrentClassloaderDetail());}public CallerClassA() {System.out.println("Creating a new instance of "+CallerClassA.class.getName()+"...");}public void doSomething() {// Create a new instance of ReferencingClassAReferencingClassA referencingClass = new ReferencingClassA();             }
}
package org.ph.javaee.training1;import org.ph.javaee.training.util.JavaEETrainingUtil;/*** ReferencingClassA* @author Pierre-Hugues Charbonneau**/
public class ReferencingClassA {private final static String CLAZZ = ReferencingClassA.class.getName();static {System.out.println("Classloading of "+CLAZZ+" in progress..."+JavaEETrainingUtil.getCurrentClassloaderDetail());}public ReferencingClassA() {System.out.println("Creating a new instance of "+ReferencingClassA.class.getName()+"...");}public void doSomething() {//nothing to do...}
}
package org.ph.javaee.training.util;import java.util.Stack;
import java.lang.ClassLoader;/*** JavaEETrainingUtil* @author Pierre-Hugues Charbonneau**/
public class JavaEETrainingUtil {/*** getCurrentClassloaderDetail* @return*/public static String getCurrentClassloaderDetail() {StringBuffer classLoaderDetail = new StringBuffer();       Stack<ClassLoader> classLoaderStack = new Stack<ClassLoader>();ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();classLoaderDetail.append("\n-----------------------------------------------------------------\n");// Build a Stack of the current ClassLoader chainwhile (currentClassLoader != null) {classLoaderStack.push(currentClassLoader);currentClassLoader = currentClassLoader.getParent();}// Print ClassLoader parent chainwhile(classLoaderStack.size() > 0) {ClassLoader classLoader = classLoaderStack.pop();// Print current                     classLoaderDetail.append(classLoader);if (classLoaderStack.size() > 0) {classLoaderDetail.append("\n--- delegation ---\n");                               } else {classLoaderDetail.append(" **Current ClassLoader**");}}classLoaderDetail.append("\n-----------------------------------------------------------------\n");return classLoaderDetail.toString();}
}

問題重現

為了重現該問題,我們將簡單地“自愿”從包含引用Java類ReferencingClassA的類路徑中省略其中一個JAR文件。

Java程序的包裝如下:
– MainProgram.jar(包含NoClassDefFoundErrorSimulator.class和JavaEETrainingUtil.class)
-CallerClassA.jar(包含CallerClassA.class) – ReferencingClassA.jar(包含ReferencingClassA.class)

現在,讓我們按原樣運行程序:

建議和解決策略

##基準(正常執行)

..\bin>java -classpath CallerClassA.jar;ReferencingClassA.jar;MainProgram.jar org.ph.javaee.training1.NoClassDefFoundErrorSimulatorjava.lang.NoClassDefFoundError Simulator - Training 1
Author: Pierre-Hugues Charbonneau
http://javaeesupportpatterns.blogspot.comCurrent ClassLoader chain:
-----------------------------------------------------------------
sun.misc.Launcher$ExtClassLoader@17c1e333
--- delegation ---
sun.misc.Launcher$AppClassLoader@214c4ac9 **Current ClassLoader**
-----------------------------------------------------------------Classloading of org.ph.javaee.training1.CallerClassA in progress...
-----------------------------------------------------------------
sun.misc.Launcher$ExtClassLoader@17c1e333
--- delegation ---
sun.misc.Launcher$AppClassLoader@214c4ac9 **Current ClassLoader**
-----------------------------------------------------------------Creating a new instance of org.ph.javaee.training1.CallerClassA...
Classloading of org.ph.javaee.training1.ReferencingClassA in progress...
-----------------------------------------------------------------
sun.misc.Launcher$ExtClassLoader@17c1e333
--- delegation ---
sun.misc.Launcher$AppClassLoader@214c4ac9 **Current ClassLoader**
-----------------------------------------------------------------Creating a new instance of org.ph.javaee.training1.ReferencingClassA...
done!

發生了什么? 刪除包含ReferencingClassA的ReferencingClassA.jar確實阻止了當前類加載器在運行時定位此引用Java類,從而導致ClassNotFoundException和NoClassDefFoundError。

如果您從Java啟動類路徑中或Java EE相關應用程序的EAR / WAR中省略JAR文件,這將是典型的異常。

ClassLoader視圖

現在,讓我們回顧一下ClassLoader鏈,以便您可以正確地了解這種問題情況。 從Java程序輸出日志記錄中可以看到,找到了以下Java ClassLoader:

Classloading of org.ph.javaee.training1.CallerClassA in progress...
-----------------------------------------------------------------
sun.misc.Launcher$ExtClassLoader@17c1e333
--- delegation ---
sun.misc.Launcher$AppClassLoader@214c4ac9 **Current ClassLoader**
-----------------------------------------------------------------

**請注意,Java引導類加載器負責加載核心JDK類,并以本機代碼編寫**

## sun.misc.Launcher $ AppClassLoader

這是系統類加載器,負責加載在啟動時指定的Java類路徑中找到的應用程序代碼。

## sun.misc.Launcher $ ExtClassLoader

這是擴展類加載器,負責將代碼加載到擴展目錄(<java_home> / lib / ext或java.ext.dirs系統屬性指定的任何其他目錄)中。

從Java程序日志輸出中可以看到,擴展類加載器是系統類加載器的實際超級父級。 我們的示例Java程序是在系統類加載器級別加載的。 請注意,對于這種問題情況,該類加載器鏈非常簡單,因為我們此時尚未創建子類加載器。 這將在以后的文章中介紹。

建議和解決策略

現在在下面找到我對NoClassDefFoundError問題案例1的建議和解決策略:

–檢查java.lang.NoClassDefFoundError錯誤并確定缺少的Java類
-在編譯/構建環境中驗證并找到丟失的Java類
-確定缺少的Java類是來自應用程序代碼,第三方API還是Java EE容器本身。 驗證預期在哪里找到丟失的JAR文件 –找到后,驗證您的運行時環境Java類路徑是否存在任何拼寫錯誤或丟失的JAR文件 –如果問題是由Java EE應用程序觸發的,請執行與上述相同的步驟,但請驗證EAR / WAR文件的包裝是否缺少JAR和其他庫文件依賴項(如MANIFEST)。

請隨時發表任何問題或評論。 第3部分將很快上市。

參考: java.lang.NoClassDefFoundError:如何解決–第2部分,來自我們的JCG合作伙伴 Pierre-Hugues Charbonneau,位于Java EE支持模式和Java教程博客。


翻譯自: https://www.javacodegeeks.com/2012/06/this-article-is-part-2-of-our.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372644.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372644.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372644.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android開發技術周報 Issue#34

教程 Google Develop for Android 系列 前幾天在G上看到Google Developers站點&#xff0c;有一個Android系列的文章&#xff0c;分享到個人微博&#xff0c;周末閑來沒事就學寫了下&#xff0c;把它們簡單的翻譯了下&#xff0c;沒想到一發不可收拾&#xff0c;六篇文章全部都…

php進度條插件,分享8款優秀的 jQuery 加載動畫和進度條插件_jquery

加載動畫和進度條在網站和 Web 應用中的使用非常流行。雖然網速越來越快&#xff0c;但是我們的網站越來越復雜&#xff0c;同時用戶對網站的使用體驗的要求也越來越高。在內容加載緩慢的時候&#xff0c;使用時尚的加載動畫和進度條告訴用戶還有內容正在加載是一種非常好的方式…

卷積神經網絡(CNN)與特殊的卷積

各種卷積操作的可視化的顯示形式&#xff1a;GitHub - vdumoulin/conv_arithmetic: A technical report on convolution arithmetic in the context of deep learning1. fractionally-strided 卷積 如上圖示&#xff0c;輸入為 33 &#xff0c;想要卷積上采樣成 55 的輸出。需要…

JBoss AS 7:自定義登錄模塊

JBoss AS 7很整潔&#xff0c;但是仍然缺少文檔&#xff08;錯誤消息沒有那么有用&#xff09;。 這篇文章總結了如何創建自己的兼容JavaEE的登錄模塊&#xff0c;以對部署在JBoss AS上的Web應用程序的用戶進行身份驗證。 提供了一個工作的基本用戶名密碼模塊。 為什么要使用Ja…

MySQL安裝步驟及相關問題解決

1. 下載MySQL Server&#xff0c;網址&#xff1a;http://dev.mysql.com/downloads/mysql/ 2. 點擊MySQL5.5.21的安裝文件&#xff0c;出現安裝向導界面&#xff0c;單擊“next”繼續安裝&#xff1a; 3. 選擇接受協議&#xff0c;單擊“next”繼續安裝&#xff1a; 4. 在出現選…

matlab的數學函數,matlab中常見數學函數的使用

matlab中常見數學函數的使用 MATLAB 基本知識 Matlab 的內部常數 pi 圓周率 exp(1) 自然對數的底數 e i 或 j 虛數單位 Inf 或 inf 無窮大 Matlab 的常用內部數學函數 指數函數 exp(x) 以 e 為底數 log(x) 自然對數&#xff0c;即以 e 為底數的對數 log10(x) 常用對數&#xff…

C++中 list與vector的區別

C中 list與vector的區別 引用http://www.cnblogs.com/shijingjing07/p/5587719.html C vector和list的區別 1.vector數據結構vector和數組類似&#xff0c;擁有一段連續的內存空間&#xff0c;并且起始地址不變。因此能高效的進行隨機存取&#xff0c;時間復雜度為o(1);但因為內…

使用Struts 2的查詢網格(無插件)

當將jQuery與struts 2一起使用時&#xff0c;開發人員被說服使用struts2-jQuery插件 。 因為大多數論壇和其他Internet資源都支持struts2 jQuery插件。我有這種經驗。 我想將Struts 2使用jQuery Grid插件&#xff0c;但不使用struts2 jQuery插件。 對于我而言&#xff0c;很難找…

php reflectionmethod,PHP ReflectionMethod getClosure()用法及代碼示例

ReflectionMethod::getClosure()函數是PHP中的一個內置函數&#xff0c;用于為該方法返回動態創建的閉包&#xff0c;否則&#xff0c;在出現錯誤的情況下返回NULL。用法:Closure ReflectionMethod::getClosure ( $object )參數&#xff1a;該函數接受參數對象&#xff0c;該參…

java學習筆記--IO流

第十二章大綱&#xff1a; I/O input/output 輸入/輸出 一、創建文件&#xff0c;借助File類來實現 file.createNewFile() &#xff1a; 創建文件 file.exists() &#xff1a; 判斷文件是否存在&#xff0c;如果存在&#xff0c;則返回true delete() &#xff1a; 刪除文件&…

linux命令之kill篇

作業四&#xff1a;查詢firewall進程&#xff0c;然后殺死 [rootlocalhost 桌面]# ps -aux |grep firewall root 772 0.0 2.0 327912 20704 ? Ssl 15:23 0:00 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid root 5323 0.0 0.0 112660…

ActiveMQ網絡連接器

這篇文章對我和任何對網絡連接器如何為ActiveMQ工作感興趣的ActiveMQ貢獻者而言都是更多的內容。 我最近花了一些時間查看代碼&#xff0c;并認為最好畫一些快速的圖表來幫助我記住我學到的東西&#xff0c;并在將來發現問題時幫助將來確定在哪里進行調試。 如果我輸入有誤&…

《程序設計與數據結構》第3周學習總結

學號 20162317 《程序設計與數據結構》第3周學習總結 教材學習內容總結 第三章的內容相比之前兩章更為具體&#xff0c;介紹的內容更為集中&#xff0c;主要說到了類和對象的問題&#xff0c;其中也仔細介紹了String類、Random類、Math類、NumberFormat類等類。此外也說到了與類…

Java中帶有JWebSocket的WebServerSocket

首先&#xff0c;轉到http://jwebsocket.org/下載2個軟件包Server and Client。 如果要查看源代碼&#xff0c;請下載源代碼包。 服務器 解壓縮服務器程序包。 轉到“ conf”文件夾 選擇“ jWebSocket.xml”文件打開 編輯“ jWebSocket.xml”文件&#xff0c;在標簽<dom…

OpenCV入門指南----人臉檢測

本篇介紹圖像處理與模式識別中最熱門的一個領域——人臉檢測&#xff08;人臉識別&#xff09;。人臉檢測可以說是學術界的寵兒&#xff0c;在不少EI&#xff0c;SCI高級別論文都能看到它的身影。甚至很多高校學生的畢業設計都會涉及到人臉檢測。當然人臉檢測的巨大實用價值也讓…

matlab提取艾里斑,艾里斑:我不是雀斑

正是艾里斑&#xff0c;限制了光學儀器的精度我們知道凸透鏡能把入射光會聚到它的焦點上&#xff0c;由于透鏡的口徑有一定大小&#xff0c;限制了光線的傳播&#xff0c;所以凸透鏡也會發生衍射。這導致透鏡無法把光線會聚成無限小的點&#xff0c;而只會在焦點上形成具有一定…

mysql啟動錯誤排查-無法申請足夠內存

一般情況下mysql的啟動錯誤還是很容易排查的&#xff0c;但是今天我們就來說一下不一般的情況。拿到一臺服務器&#xff0c;安裝完mysql后進行啟動&#xff0c;啟動錯誤如下&#xff1a; 有同學會說&#xff0c;哥們兒你是不是buffer pool設置太大了&#xff0c;設置了96G內存。…

Spring vs Guice:重要的一個關鍵區別

根據彈簧對象的名稱識別它們 不管使用XML還是Java配置都沒有關系&#xff0c;Spring范圍大致類似于Map <String&#xff0c;Object>結構。 這意味著您不能有兩個名稱相同的對象 。 為什么這是一件壞事&#xff1f; 如果您的大型應用程序包含許多Configuration類或XML文件…

php 批量更新死鎖,php – 在嘗試獲取鎖定時,哪個查詢導致死鎖;嘗試重新啟動事務...

我無法弄清楚哪個Query在嘗試獲取鎖定時導致死鎖;嘗試重新啟動事務.我的mysql包裝器有以下幾行if (mysql_errno($this->conn) 1213) {$this->bug_log(0,"Deadlock. SQL:".$this->sql);}bug_log寫入文件的位置.錯誤日志文件沒有死鎖錯誤,但/var/log/mysqld.…

Task和BackTask

一、總結性知識點&#xff1a; 1、Android應用運行時會創建任務Task&#xff0c;用于存放主窗口2、每一個任務包含一個堆棧數據結構&#xff0c;用于保存當前應用已創建的窗口對象&#xff0c;這個堆棧即回退棧BackStack3&#xff64; 位于回退棧頂的窗口會處于焦點狀態4&#…