GVKun编程网logo

将jsoup添加为提供的依赖项后,Storm命令失败,并显示NoClassDefFoundError

13

此处将为大家介绍关于将jsoup添加为提供的依赖项后,Storm命令失败,并显示NoClassDefFoundError的详细内容,此外,我们还将为您介绍关于ClassNotFoundExceptio

此处将为大家介绍关于将jsoup添加为提供的依赖项后,Storm命令失败,并显示NoClassDefFoundError的详细内容,此外,我们还将为您介绍关于ClassNotFoundException 和 NoClassDefFoundError、ClassNotFoundException 和 NoClassDefFoundError 区别、ClassNotFoundException 和 NoClassDefFoundError 有什么区别?、ClassNotFoundException 和 NoClassDefFoundError 的区别的有用信息。

本文目录一览:

将jsoup添加为提供的依赖项后,Storm命令失败,并显示NoClassDefFoundError

将jsoup添加为提供的依赖项后,Storm命令失败,并显示NoClassDefFoundError

我在项目中使用JSoup,并在POM文件中声明了依赖项。它可以很好地编译并且也可以很好地运行,但是仅当我使用jar with alldependencies和时,将依赖项的范围更改为compiled

如果将范围更改为provided,则仍然可以编译,但不能运行它。它给了我ClassNotFoundException。我在classpathpath变量中都包含了必要的JAR文件,但我仍然面临着这个问题。

我可以用编译选项工作,但它的真正irking我在我的脑海里,为什么我不能把它与所提供的选项运行,我就 真的很 感激,如果有人可以帮助我弄清楚为什么。

以下是我看到的错误:

java.lang.NoClassDefFoundError: Lorg/jsoup/nodes/Document;    at java.lang.Class.getDeclaredFields0(Native Method)    at java.lang.Class.privateGetDeclaredFields(Class.java:2300)    at java.lang.Class.getDeclaredField(Class.java:1882)    at java.io.ObjectStreamClass.getDeclaredSUID(ObjectStreamClass.java:1605)    at java.io.ObjectStreamClass.access$700(ObjectStreamClass.java:50)    at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:423)    at java.security.AccessController.doPrivileged(Native Method)    at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:411)    at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:308)    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1114)    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)    at backtype.storm.utils.Utils.serialize(Utils.java:52)    at backtype.storm.topology.TopologyBuilder.createTopology(TopologyBuilder.java:94)    at com.yahoo.amit.wordstorm.WordStormTopology.main(WordStormTopology.java:25)Caused by: java.lang.ClassNotFoundException: org.jsoup.nodes.Document    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)    at java.security.AccessController.doPrivileged(Native Method)    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)    ... 14 more

以下是我的POM文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.yahoo.amit.wordstorm</groupId>  <artifactId>wordstorm</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>jar</packaging>  <name>wordstorm</name>  <url>http://maven.apache.org</url>    <repositories>        <repository>            <id>clojars.org</id>            <url>http://clojars.org/repo</url>        </repository>    </repositories>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  </properties>  <dependencies>    <dependency>            <groupId>storm</groupId>            <artifactId>storm</artifactId>            <version>0.8.2</version>            <scope>provided</scope>        </dependency>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>test</scope>    </dependency>    <dependency>    <groupId>org.jsoup</groupId>    <artifactId>jsoup</artifactId>    <version>1.7.2</version>    <scope>provided</scope></dependency>  </dependencies>  <build>    <plugins>            <!--            bind the maven-assembly-plugin to the package phase            this will create a jar file without the storm dependencies            suitable for deployment to a cluster.             -->            <plugin>                <artifactId>maven-assembly-plugin</artifactId>                <configuration>                    <descriptorRefs>                        <descriptorRef>jar-with-dependencies</descriptorRef>                    </descriptorRefs>                    <archive>                        <manifest>                            <mainClass></mainClass>                        </manifest>                    </archive>                </configuration>                <executions>                    <execution>                        <id>make-assembly</id>                        <phase>package</phase>                        <goals>                            <goal>single</goal>                        </goals>                    </execution>                </executions>            </plugin>        </plugins>        </build></project>

以下是我的系统变量:

echo $PATH/Users/programmerman/SummerProject/apache-maven-3.0.5/bin/:/Users/programmerman/Summer

Project/storm-0.8.2/bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/programmerman/Summer
Project/CLASSPATH/jsoup-1.7.2.jar:/Users/programmerman/Summer
Project/CLASSPATH/*

echo $CLASSPATH/Users/programmerman/SummerProject/storm-0.8.2/storm-0.8.2.jar:/Users/programmerman/SummerProject/storm-0.8.2/lib/*:/Users/programmerman/Summer

Project/storm-0.8.2/conf/storm.yaml:/Users/programmerman/SummerProject/storm-
starter-masterPOM/target/storm-starter-0.0.1-SNAPSHOT-jar-with-
dependencies.jar:/Users/programmerman/Summer
Project/CLASSPATH/jsoup-1.7.2.jar:/Users/programmerman/Summer
Project/CLASSPATH/*

答案1

小编典典

这既是关于Maven的问题,也是关于Storm及其部署模型的问题。您必须检查该storm命令的实际作用。首先,它实际上是一个最终调用的Python脚本java

如果您看一下函数get_classpath(extrajars),您会注意到它根本不使用$CLASSPATHevironment变量。相反,它将加载核心Storm
jar和lib/相对于工作目录的目录下的所有jar,以及以下目录中的配置文件~/.storm

(您会发现忽略$CLASSPATH在许多Java应用程序中非常普遍。通常,“启动脚本”所做的第一件事是覆盖CLASSPATH或根本不使用它。这是为了防止导致未知/不支持/早期版本的jar。应用程序中的问题)。

至于在将jsoup声明为“提供”时您的应用程序失败:当将jar声明为提供的依赖项时,它将不会打包在“带有依赖项的jar”程序集中。请参见以下问题以获取良好的解释:Maven范围编译与JAR打包所提供的区别

tl; dr的解释是,编译范围是随uber-jar一起提供的,但前提是没有,因为预期它是由部署到的容器“提供”的。通常,“容器”是Java
Web服务器,例如Tomcat(因此,您永远不必随Java一起发布JSP或Servlet
jar)。在这种情况下,您希望“提供”类的“容器”是Storm。但是,Storm不提供jsoup,因此会出错。

编译范围类仍需要随应用程序一起提供,因为您的应用程序将实例化/使用接口,枚举等。

我的建议是只声明jsoup“编译”范围并继续。替代方法是编写您自己的定制部署脚本和/或程序集,将jsoup置于其下lib/-基本上是同一件事。

ClassNotFoundException 和 NoClassDefFoundError

ClassNotFoundException 和 NoClassDefFoundError

1. 概述
java.lang.NoClassDefFoundError 和 java.lang.ClassNotFoundException 都是 Java 语言层面的异常

NoClassDefFoundError :Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class and no definition of the class could be found. 在 ClassLoader.loadClass () 方法中抛出 ClassNotFoundException : Thrown when an application tries to load in a class through its string name using:forName、findSystemClass、loadClas but no definition for the class with the specified name could be found.;在 ClassLoader.defineClass () 中抛出

本质性区别: 
NoClassDefFoundError 是程序在编译时候可以顺利找到所需要依赖的类的,但是在运行时依赖的类找不到或者可以找到多个,就会抛出这个 Error。ClassNotFoundException 在类路径错误,或者类名称发生更改,都会导致这个 Exception,这两个异常的出现在生产环境中,通常是由于依赖 jar 包多版本存在,jar 包升级中类或者方法不再提供引起的

2. 测试代码

package com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef;

import com.vip.vcp.ryan.zhaunzheng.map.PHashMap426.PLinkedHashMap;

import java.util.LinkedHashMap;
import java.util.Scanner;

/**
 * 模拟ClassNotFoundException和 NoClassDefFoundError两个异常
 * Created by ryan01.peng on 2017/5/8.
 */
public class TestClassAboutException {

    public static void main(String[] args) {
        System.out.println("---》》》TestClassAboutException编译已经通过啦!!!");
        toShowClassNotFoundException();
        toShowNoClassDefErr();
        toShowNoClassDefErr2();

    }

    public static  void  toShowClassNotFoundException(){
        try {
            //"com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException"
            // 模拟jar包路劲改变或者,类名称改变引起的ClassNotFoundException
            Class cl = Class.forName("vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException");// TestClassAboutException.class.getName()

            System.out.println("---》》》toShowClassNotFoundException ::: "+cl.getName());
        } catch (ClassNotFoundException e) {
            System.out.println("---》》》ClassNotFoundException 被捕捉到啦!!!");
            e.printStackTrace();
        }
    }

    public static  void toShowNoClassDefErr(){

        Scanner scanner = new Scanner(System.in);
        System.out.println("/n"+"是否进入NoClassDefErr复现环节: 输入1/0   ");
        //阻塞,删去类文件
        if (scanner.nextInt() == 1)
        {
            try {
                //com.vip.vcp.ryan.zhaunzheng.map.PHashMap426.PLinkedHashMap
                // 模拟在运行时,类文件丢失,则会产生NoClassDefFoundError
                Class c = Class.forName(PLinkedHashMap.class.getName());

                System.out.println("---》》》toShowNoClassDefErr :::" +c.getName());
            } catch (ClassNotFoundException e) {
                System.out.println("---》》》NoClassDefErr 被捕捉啦!!!");
                e.printStackTrace();
            }
        }
        else
            return;
    }

    public static  void toShowNoClassDefErr2(){
        Scanner scanner = new Scanner(System.in);
        System.out.println("/n"+"是否进入NoClassDefErr复现环节: 输入1/0   ");
        if (scanner.nextInt() == 1)
        {
            try {
                B bS = new B();
            } catch (Throwable e) {
                e.printStackTrace();
            }
            B b = new B();
        }
    }
}

初始化失败类 B

import java.util.HashMap;
import java.util.Map;

/**
 * Created by ryan01.peng on 2017/5/8.
 */

public class B {
    static {
           init();
    }
    public B() {
    }

    static void init(){
        System.out.println("B initializing and then Exception occurred");
        int re = 5/0;
        System.out.println(re);
    }
}

测试输出

"C:\Program Filcom.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException
java.lang.ClassNotFoundException: vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:191)
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException.toShowClassNotFoundException(TestClassAboutException.java:23)
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException.main(TestClassAboutException.java:15)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
---》》》TestClassAboutException编译已经通过啦!!!
---》》》ClassNotFoundException 被捕捉到啦!!!
null
/n是否进入NoClassDefErr复现环节: 输入1/0   
1
Exception in thread "main" java.lang.NoClassDefFoundError: com/vip/vcp/ryan/zhaunzheng/map/PHashMap426/PLinkedHashMap
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException.toShowNoClassDefErr(TestClassAboutException.java:41)
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException.main(TestClassAboutException.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.ClassNotFoundException: com.vip.vcp.ryan.zhaunzheng.map.PHashMap426.PLinkedHashMap
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 7 more

Process finished with exit code 1

由于静态代码块初始化失败引起的 NoClassDefFoundError

---》》》TestClassAboutException编译已经通过啦!!!
/n是否进入NoClassDefErr复现环节: 输入1/0   
1
B initializing and then Exception occurred
java.lang.ExceptionInInitializerError
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException.toShowNoClassDefErr2(TestClassAboutException.java:63)
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException.main(TestClassAboutException.java:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.ArithmeticException: / by zero
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.B.init(B.java:24)
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.B.<clinit>(B.java:16)
    ... 7 more
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.B
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException.toShowNoClassDefErr2(TestClassAboutException.java:67)
    at com.vip.vcp.ryan.zhaunzheng.ToLeExcep.ClassNotFoundAndNoClassDef.TestClassAboutException.main(TestClassAboutException.java:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Process finished with exit code 1

在日常 Java 开发中,我们经常碰到 java.lang.NoClassDefFoundError 这样的错误,需要花费很多时间去找错误的原因,具体是哪个类不见了?类明明还在,为什么找不到?而且我们很容易把 java.lang.NoClassDefFoundError 和 java.lang.ClassNotfoundException 这两个错误搞混,事实上这两个错误是完全不同的。我们往往花费时间去不断尝试一些其他的方法去解决这个问题,而没有真正去理解这个错误的原因。这篇文章就是通过解决 NoClassDefFoundError 错误处理的经验分享来揭开 NoClassDefFoundError 的一些秘密。NoClassDefFoundError 的错误并非不能解决或者说很难解决,只是这种错误的表现形式很容易迷惑其他的 Java 开发者。下面我们来分析下为什么会发生 NoClassDefFoundError 这样的错误,以及怎样去解决这个错误。

NoClassDefFoundError 错误发生的原因

NoClassDefFoundError 错误的发生,是因为 Java 虚拟机在编译时能找到合适的类,而在运行时不能找到合适的类导致的错误。例如在运行时我们想调用某个类的方法或者访问这个类的静态成员的时候,发现这个类不可用,此时 Java 虚拟机就会抛出 NoClassDefFoundError 错误。与 ClassNotFoundException 的不同在于,这个错误发生只在运行时需要加载对应的类不成功,而不是编译时发生。很多 Java 开发者很容易在这里把这两个错误搞混。

简单总结就是,NoClassDefFoundError 发生在编译时对应的类可用,而运行时在 Java 的 classpath 路径中,对应的类不可用导致的错误。发生 NoClassDefFoundError 错误时,你能看到如下的错误日志:

Exception in thread "main" java.lang.NoClassDefFoundError

错误的信息很明显地指明 main 线程无法找到指定的类,而这个 main 线程可能时主线程或者其他子线程。如果是主线程发生错误,程序将崩溃或停止,而如果是子线程,则子线程停止,其他线程继续运行。

NoClassDefFoundError 和 ClassNotFoundException 区别

我们经常被 java.lang.ClassNotFoundException 和 java.lang.NoClassDefFoundError 这两个错误迷惑不清,尽管他们都与 Java classpath 有关,但是他们完全不同。NoClassDefFoundError 发生在 JVM 在动态运行时,根据你提供的类名,在 classpath 中找到对应的类进行加载,但当它找不到这个类时,就发生了 java.lang.NoClassDefFoundError 的错误,而 ClassNotFoundException 是在编译的时候在 classpath 中找不到对应的类而发生的错误。ClassNotFoundException 比 NoClassDefFoundError 容易解决,是因为在编译时我们就知道错误发生,并且完全是由于环境的问题导致。而如果你在 J2EE 的环境下工作,并且得到 NoClassDefFoundError 的异常,而且对应的错误的类是确实存在的,这说明这个类对于类加载器来说,可能是不可见的。

怎么解决 NoClassDefFoundError 错误

根据前文,很明显 NoClassDefFoundError 的错误是因为在运行时类加载器在 classpath 下找不到需要加载的类,所以我们需要把对应的类加载到 classpath 中,或者检查为什么类在 classpath 中是不可用的,这个发生可能的原因如下:

  1. 对应的 Class 在 java 的 classpath 中不可用
  2. 你可能用 jar 命令运行你的程序,但类并没有在 jar 文件的 manifest 文件中的 classpath 属性中定义
  3. 可能程序的启动脚本覆盖了原来的 classpath 环境变量
  4. 因为 NoClassDefFoundError 是 java.lang.LinkageError 的一个子类,所以可能由于程序依赖的原生的类库不可用而导致
  5. 检查日志文件中是否有 java.lang.ExceptionInInitializerError 这样的错误,NoClassDefFoundError 有可能是由于静态初始化失败导致的
  6. 如果你工作在 J2EE 的环境,有多个不同的类加载器,也可能导致 NoClassDefFoundError

下面我们看一些当发生 NoClassDefFoundError 时,我们该如何解决的样例。

NoClassDefFoundError 解决示例

当发生由于缺少 jar 文件,或者 jar 文件没有添加到 classpath,或者 jar 的文件名发生变更会导致 java.lang.NoClassDefFoundError 的错误。当类不在 classpath 中时,这种情况很难确切的知道,但如果在程序中打印出 System.getproperty (“java.classpath”),可以得到程序实际运行的 classpath 运行时明确指定你认为程序能正常运行的 -classpath 参数,如果增加之后程序能正常运行,说明原来程序的 classpath 被其他人覆盖了。
NoClassDefFoundError 也可能由于类的静态初始化模块错误导致,当你的类执行一些静态初始化模块操作,如果初始化模块抛出异常,哪些依赖这个类的其他类会抛出 NoClassDefFoundError 的错误。如果你查看程序日志,会发现一些 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 的错误在依赖其他的类时会发生,所以如果你的程序依赖原生的类库和需要的 dll 不存在时,有可能出现 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 这样多用户的操作系统种,你需要把你应用相关的资源文件,如 Jar 文件,类库文件,配置文件的权限单独分配给程序所属用户组,如果你使用了多个用户不同程序共享的 jar 包时,很容易出现权限问题。比如其他用户应用所属权限的 jar 包你的程序没有权限访问,会导致 java.lang.NoClassDefFoundError 的错误。
基于 XML 配置的程序也可能导致 NoClassDefFoundError 的错误。比如大多数 Java 的框架像 Spring,Struts 使用 xml 配置获取对应的 bean 信息,如果你输入了错误的名称,程序可能会加载其他错误的类而导致 NoClassDefFoundError 异常。我们在使用 Spring MVC 框架或者 Apache Struts 框架,在部署 War 文件或者 EAR 文件时就经常会出现 Exception in thread “main” java.lang.NoClassDefFoundError。
在有多个 ClassLoader 的 J2EE 的环境中,很容易出现 NoClassDefFoundError 的错误。由于 J2EE 没有指明标准的类加载器,使用的类加载器依赖与不同的容器像 Tomcat、WebLogic,WebSphere 加载 J2EE 的不同组件如 War 包或者 EJB-JAR 包。关于类加载器的相关知识可以参考这篇文章类加载器的工作原理。

总结来说,类加载器基于三个机制:委托、可见性和单一性,委托机制是指将加载一个类的请求交给父类加载器,如果这个父类加载器不能够找到或者加载这个类,那么再加载它。可见性的原理是子类的加载器可以看见所有的父类加载器加载的类,而父类加载器看不到子类加载器加载的类。单一性原理是指仅加载一个类一次,这是由委托机制确保子类加载器不会再次加载父类加载器加载过的类。现在假设一个 User 类在 WAR 文件和 EJB-JAR 文件都存在,并且被 WAR ClassLoader 加载,而 WAR ClassLoader 是加载 EJB-JAR ClassLoader 的子 ClassLoader。当 EJB-JAR 中代码引用这个 User 类时,加载 EJB-JAR 所有 class 的 Classloader 找不到这个类,因为这个类已经被 EJB-JAR classloader 的子加载器 WAR classloader 加载。

这会导致的结果就是对 User 类出现 NoClassDefFoundError 异常,而如果在两个 JAR 包中这个 User 类都存在,如果你使用 equals 方法比较两个类的对象时,会出现 ClassCastException 的异常,因为两个不同类加载器加载的类无法进行比较。
有时候会出现 Exception in thread “main” java.lang.NoClassDefFoundError: com/sun/tools/javac/Main 这样的错误,这个错误说明你的 Classpath, PATH 或者 JAVA_HOME 没有安装配置正确或者 JDK 的安装不正确。这个问题的解决办法时重新安装你的 JDK。
Java 在执行 linking 操作的时候,也可能导致 NoClassDefFoundError。例如在前面的脚本中,如果在编译完成之后,我们删除 User 的编译文件,再运行程序,这个时候你就会直接得到 NoClassDefFoundError,而错误的消息只打印出 User 类的名称。

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

 

 

ClassNotFoundException 和 NoClassDefFoundError 区别

ClassNotFoundException 和 NoClassDefFoundError 区别

【直播预告】程序员逆袭 CEO 分几步?

在写 Java 程序的时候,当一个类找不到的时候,JVM 有时候会抛出 ClassNotFoundException 异常,而有时候又会抛出 NoClassDefFoundError。看两个异常的字面意思,好像都是类找不到,但是 JVM 为什么要用两个异常去区分类找不到的情况呢?这个两个异常有什么不同的地方呢?

ClassNotFoundException

ClassNotFoundException 是一个运行时异常。从类继承层次上来看,ClassNotFoundException 是从 Exception 继承的,所以 ClassNotFoundException 是一个检查异常。

图片

当应用程序运行的过程中尝试使用类加载器去加载 Class 文件的时候,如果没有在 classpath 中查找到指定的类,就会抛出 ClassNotFoundException。一般情况下,当我们使用 Class.forName () 或者 ClassLoader.loadClass 以及使用 ClassLoader.findSystemClass () 在运行时加载类的时候,如果类没有被找到,那么就会导致 JVM 抛出 ClassNotFoundException。

最简单的,当我们使用 JDBC 去连接数据库的时候,我们一般会使用 Class.forName () 的方式去加载 JDBC 的驱动,如果我们没有将驱动放到应用的 classpath 下,那么会导致运行时找不到类,所以运行 Class.forName () 会抛出 ClassNotFoundException。

public class MainClass {
    public static void main(String[] args) {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出:

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at MainClass.main(MainClass.java:7)

NoClassDefFoundError

NoClassDefFoundError 异常,看命名后缀是一个 Error。从类继承层次上看,NoClassDefFoundError 是从 Error 继承的。和 ClassNotFoundException 相比,明显的一个区别是,NoClassDefFoundError 并不需要应用程序去关心 catch 的问题。

图片

当 JVM 在加载一个类的时候,如果这个类在编译时是可用的,但是在运行时找不到这个类的定义的时候,JVM 就会抛出一个 NoClassDefFoundError 错误。比如当我们在 new 一个类的实例的时候,如果在运行是类找不到,则会抛出一个 NoClassDefFoundError 的错误。

public class TempClass {
}

public class MainClass {
    public static void main(String[] args) {
        TempClass t = new TempClass();
    }
}

首先这里我们先创建一个 TempClass,然后编译以后,将 TempClass 生产的 TempClass.class 文件删除,然后执行程序,输出:

Exception in thread "main" java.lang.NoClassDefFoundError: TempClass
    at MainClass.main(MainClass.java:6)
Caused by: java.lang.ClassNotFoundException: TempClass
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

总结

图片

ClassNotFoundException 和 NoClassDefFoundError 有什么区别?

ClassNotFoundException 和 NoClassDefFoundError 有什么区别?

身处险境的人总在谋求安稳,活于规则的人又在追逐自由。

在写Java程序的时候,当一个类找不到的时候,JVM有时候会抛出ClassNotFoundException异常,而有时候又会抛出NoClassDefFoundError。看两个异常的字面意思,好像都是类找不到,但是JVM为什么要用两个异常去区分类找不到的情况呢?这个两个异常有什么不同的地方呢?

ClassNotFoundException

ClassNotFoundException是一个运行时异常。从类继承层次上来看,ClassNotFoundException是从Exception继承的,所以ClassNotFoundException是一个检查异常。
image
当应用程序运行的过程中尝试使用类加载器去加载Class文件的时候,如果没有在classpath中查找到指定的类,就会抛出ClassNotFoundException。一般情况下,当我们使用Class.forName()或者ClassLoader.loadClass以及使用ClassLoader.findSystemClass()在运行时加载类的时候,如果类没有被找到,那么就会导致JVM抛出ClassNotFoundException。

最简单的,当我们使用JDBC去连接数据库的时候,我们一般会使用Class.forName()的方式去加载JDBC的驱动,如果我们没有将驱动放到应用的classpath下,那么会导致运行时找不到类,所以运行Class.forName()会抛出ClassNotFoundException。

public class MainClass {
    public static void main(String[] args) {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出:

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at MainClass.main(MainClass.java:7)

NoClassDefFoundError

NoClassDefFoundError异常,看命名后缀是一个Error。从类继承层次上看,NoClassDefFoundError是从Error继承的。和ClassNotFoundException相比,明显的一个区别是,NoClassDefFoundError并不需要应用程序去关心catch的问题。
image
当JVM在加载一个类的时候,如果这个类在编译时是可用的,但是在运行时找不到这个类的定义的时候,JVM就会抛出一个NoClassDefFoundError错误。比如当我们在new一个类的实例的时候,如果在运行是类找不到,则会抛出一个NoClassDefFoundError的错误。

public class TempClass {
}
public class MainClass {
    public static void main(String[] args) {
        TempClass t = new TempClass();
    }
}

首先这里我们先创建一个TempClass,然后编译以后,将TempClass生产的TempClass.class文件删除,然后执行程序,输出:

Exception in thread "main" java.lang.NoClassDefFoundError: TempClass
    at MainClass.main(MainClass.java:6)
Caused by: java.lang.ClassNotFoundException: TempClass
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

总结

image

ClassNotFoundException 和 NoClassDefFoundError 的区别

ClassNotFoundException 和 NoClassDefFoundError 的区别

  1. NoClassDefFoundError 是一个错误 (Error),而 ClassNOtFoundException 是一个异常,在 Java 中错误和异常是有区别的,我们可以从异常中恢复程序但却不应该尝试从错误中恢复程序。

      1)加载时从外存储器找不到需要的 class 就出现 ClassNotFoundException 
      2)连接时从内存找不到需要的 class 就出现 NoClassDefFoundError

 

 

    2. ClassNotFoundException 的产生原因:

Java 支持使用 Class.forName 方法来动态地加载类,任意一个类的类名如果被作为参数传递给这个方法都将导致该类被加载到 JVM 内存中,如果这个类在类路径中没有被找到,那么此时就会在运行时抛出 ClassNotFoundException 异常。

要解决这个问题很容易,唯一需要做的就是要确保所需的类连同它依赖的包存在于类路径中。

 

    3. NoClassDefFoundError 产生的原因:

如果 JVM 或者 ClassLoader 实例尝试加载(可以通过正常的方法调用,也可能是使用 new 来创建新的对象)类的时候却找不到类的定义。要查找的类在编译的时候是存在的,运行的时候却找不到了。这个错误往往是你使用 new 操作符来创建一个新的对象但却找不到该对象对应的类。这个时候就会导致 NoClassDefFoundError.

由于 NoClassDefFoundError 是有 JVM 引起的,所以不应该尝试捕捉这个错误。

解决这个问题的办法就是:查找那些在开发期间存在于类路径下但在运行期间却不在类路径下的类。

今天关于将jsoup添加为提供的依赖项后,Storm命令失败,并显示NoClassDefFoundError的介绍到此结束,谢谢您的阅读,有关ClassNotFoundException 和 NoClassDefFoundError、ClassNotFoundException 和 NoClassDefFoundError 区别、ClassNotFoundException 和 NoClassDefFoundError 有什么区别?、ClassNotFoundException 和 NoClassDefFoundError 的区别等更多相关知识的信息可以在本站进行查询。

本文标签: