奇怪的Java类NoClassDefFoundError

lep*_*hix 5 java jvm

环境:jdk1.7

javax.servlet-api-3.0.1.jar 这个测试需要.

重现步骤:

  1. javac Test1.java -cp javax.servlet-api-3.0.1.jar 使用javax.servlet-api-3.0.1.jar构建Test1.java

  2. javac Test2.java -cp javax.servlet-api-3.0.1.jar 使用javax.servlet-api-3.0.1.jar构建Test2.java

  3. javac Test3.java 构建Test3.java

  4. java -classpath .:javax.servlet-api-3.0.1.jar Test3运行具有依赖性的Test3.以下是输出.这没关系. hello world1 hello world2

  5. 但是当此命令java Test3运行时,抛出异常.这篇文章结尾的结果.奇怪的是,"hello world1"可以打印出来,但不会打印出"hello world2",而是抛出异常.

Test1.java

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
public class Test1 {
    public void getRequest(HttpServletResponse resp) throws IOException {

        OutputStream os = resp.getOutputStream();
        resp.getOutputStream().close();
    }

    public void hello(String world) {
        System.out.println("hello " + world);
    }
}
Run Code Online (Sandbox Code Playgroud)

Test2.java

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
public class Test2 {

    public void getRequest(HttpServletResponse resp) throws IOException {
        OutputStream os = resp.getOutputStream();
        try {
            resp.getOutputStream().close();
        } catch (Exception e) {
        }
    }

    public void hello(String world) {
        System.out.println("hello " + world);
    }
}
Run Code Online (Sandbox Code Playgroud)

Test3.java

public class Test3 {
    public static void main(String[] args) {
        new Test1().hello("world1");
        new Test2().hello("world2");
    }
}
Run Code Online (Sandbox Code Playgroud)

最后一步的输出.Test2.hello("world2")抛出异常:

hello world1
Exception in thread "main" java.lang.NoClassDefFoundError: javax/servlet/ServletOutputStream
    at cn.test.abc1.Test3.main(Test3.java:9)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletOutputStream
    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)
    ... 6 more
Run Code Online (Sandbox Code Playgroud)

我对Exception非常困惑.因为我没有在Class ServletOutputStream中使用任何代码.并且Test1和Test2之间的差异只是try被阻止了.

该问题不是重复的问题,因为它标记了.因为JVM在try涉及块时不应抛出异常.

lan*_*ava 0

对我来说非常有意义。Test3 引用 Test2 和 Test1,并且两者都需要javax.servlet-api-3.0.1.jar在运行时位于类路径上。