日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2023/12/3 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java.lang.NoClassDefFoundError:如何解决–第2部分 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本文是我們的NoClassDefFoundError故障排除系列的第2部分。 看一下第1部分 。 它將重點介紹最簡單的NoClassDefFoundError問題類型。 本文對于Java初學(xué)者來說是理想的選擇,我強烈建議您自己編譯并運行示例Java程序。

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

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

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

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

示例Java程序

以下簡單的Java程序按以下方式拆分:
–主Java程序NoClassDefFoundErrorSimulator
–調(diào)用者Java類CallerClassA –引用Java類ReferencingClassA –用于ClassLoader和日志記錄相關(guān)設(shè)施的util類JavaEETrainingUtil

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

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();} }

問題重現(xiàn)

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

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

現(xiàn)在,讓我們按原樣運行程序:

建議和解決策略

##基準(zhǔn)(正常執(zhí)行)

..\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!

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

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

ClassLoader視圖

現(xiàn)在,讓我們回顧一下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引導(dǎo)類加載器負責(zé)加載核心JDK類,并以本機代碼編寫**

## sun.misc.Launcher $ AppClassLoader

這是系統(tǒng)類加載器,負責(zé)加載在啟動時指定的Java類路徑中找到的應(yīng)用程序代碼。

## sun.misc.Launcher $ ExtClassLoader

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

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

建議和解決策略

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

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

請隨時發(fā)表任何問題或評論。 第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

總結(jié)

以上是生活随笔為你收集整理的java.lang.NoClassDefFoundError:如何解决–第2部分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。