“我如何解决?”;java.lang.NoClassDefFoundError“;?

“我如何解决?”;java.lang.NoClassDefFoundError“;?,java,exception,package,noclassdeffounderror,Java,Exception,Package,Noclassdeffounderror,这两个例子我都试过了。它们都可以很好地编译,但在运行时都会出现以下错误: 线程“main”java.lang.NoClassDefFoundError中的异常:图形/形状/正方形 Main.Main(Main.java:7) 原因:java.lang.ClassNotFoundException:graphics.shapes.Square 在java.net.URLClassLoader$1.run(URLClassLoader.java:366) 在java.net.URLClassLoad

这两个例子我都试过了。它们都可以很好地编译,但在运行时都会出现以下错误:

线程“main”java.lang.NoClassDefFoundError中的异常:图形/形状/正方形 Main.Main(Main.java:7) 原因:java.lang.ClassNotFoundException:graphics.shapes.Square 在java.net.URLClassLoader$1.run(URLClassLoader.java:366) 在java.net.URLClassLoader$1.run(URLClassLoader.java:355) 位于java.security.AccessController.doPrivileged(本机方法) 位于java.net.URLClassLoader.findClass(URLClassLoader.java:354) 位于java.lang.ClassLoader.loadClass(ClassLoader.java:424) 位于sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 位于java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 还有一个 我想我可能把
Main.java
文件放错文件夹了

以下是目录层次结构:

图形
├ 主类
├ 形状
|   ├ Square.java
|   ├ Triangle.java
├ 线条点
|   ├ Line.java
|   ├ Point.java
├ 空间物体
|   ├ java
|   ├ RectPrism.java
下面是
Main.java

import graphics.shapes.*;
import graphics.linepoint.*
import graphics.spaceobjects.*;

public class Main {
    public static void main(String args[]) {
        Square s = new Square(2, 3, 15);
        Line l = new Line(1, 5, 2, 3);
        Cube c = new Cube(13, 32, 22);
    }
}
我做错了什么

更新

在我将
Main
类放入
graphics
包(我在其中添加了
package graphics;
)之后,将类路径设置为“_test”(包含图形的文件夹),编译它,并使用
java graphics.Main
(从命令行)运行它

更新非常晚#2


我没有使用(只是和JDK),上面的更新解决了我的问题。然而,这些答案中似乎有许多是针对Eclipse和的,但它们有相似的概念。

NoClassDefFoundError意味着类在编译时存在于类路径中,但在运行时不存在于类路径中

如果您正在使用Eclipse,请确保将
形状
线点
空间对象
作为
.classpath
文件中的条目

java.lang.NoClassDefFoundError

指示在编译时找到了某些内容,但在运行时找不到。也许您只需要将其添加到类路径中。

编译代码后,程序中的每个类都会有
.class
文件。这些二进制文件是Java为执行程序而解释的字节码。
NoClassDefFoundError
表示负责动态加载类的类加载器(在本例中为
java.net.URLClassLoader
)找不到您尝试使用的类的
.class
文件

如果所需的类不存在,代码将无法编译(除非类加载了反射),因此通常此异常意味着您的类路径不包含所需的类。请记住,类加载器(特别是
java.net.URLClassLoader
)将在类路径的每个条目中查找文件夹a/b/c/中的包a.b.c中的类
NoClassDefFoundError
还可以指示您缺少编译所依据的.jar文件的可传递依赖项,并且您正在尝试使用该依赖项

例如,如果您有一个类
com.example.Foo
,那么编译后您将有一个类文件
Foo.class
。例如,假设您的工作目录是
../project/
。该类文件必须放在
../project/com/example
中,您可以将类路径设置为
../project/


旁注:我建议利用Java和JVM语言的惊人工具。Eclipse和IntelliJ IDEA等现代IDE以及Maven或Gradle等构建管理工具将帮助您不必担心类路径(同样多),而只需关注代码!也就是说,解释了当您在命令行上执行时如何设置类路径。

我想在
NoClassDefFoundError
上纠正其他人的观点


NoClassDefFoundError
发生的原因有多种,如:

  • ClassNotFoundException--.class找不到该引用类,无论它在编译时是否可用(即基类/子类)
  • 已找到类文件,但初始化静态变量时引发异常
  • 已找到类文件,初始化静态块时引发异常
  • 在最初的问题中,这是第一种可以通过将类路径设置为引用的类JAR文件或其包文件夹来纠正的情况

    “在编译时可用”是什么意思

    • 代码中使用了引用的类
      例如:两类,A和B(扩展A)。如果B在代码中直接引用,则它在编译时可用,即,
      aaa=newb()
    “编译时不可用”是什么意思

    • 编译时类和运行时类是不同的,例如,基类是使用子类的classname加载的 Class.forName(“classname”) 例如:两类,A和B(扩展A)。代码有
      aa=Class.forName(“B”).newInstance()

    如果您的项目位于类似
    com.blahcode
    的包中,并且您的类名为
    Main
    ,则编译后的文件可能会以类似
    /out/com/blahcode/Main.class
    的目录结构输出。这对于IntelliJ IDEA尤其如此

    当尝试从shell或cmd运行时,需要将
    cd
    转换为包含
    com
    作为子目录的目录

    cd out
    java -classpath . com.blahcode.Main
    

    如果在编译和运行时出现以下错误之一:

    • NoClassDefFoundError

    • 错误:无法找到或加载主类hello

    • 线程“main”java.lang.NoClassDefFoundError中出现异常:javaTest/test/hello (错误名称:test/hello)

      java.lang.Clas上的
      
      
      javac -d . [FileName.java]
      
      java [Package].[ClassName]
      
      public class ClassA{
          public static void main(String args[]){
               // Some gibberish code...
               String text = ClassB.getString();
               System.out.println("Text is: " + text);
          }
      }
      
      public class ClassB{
          public static String getString(){
              return "Testing some exception";
          }
      }
      
      // ClassLoaderTracer.java
      // From: https://blogs.oracle.com/sundararajan/entry/tracing_class_loading_1_5
      
      import java.lang.instrument.*;
      import java.security.*;
      
      // manifest.mf
      // Premain-Class: ClassLoadTracer
      
      // jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class
      
      // java -javaagent:tracer.jar  [...]
      
      public class ClassLoadTracer
      {
          public static void premain(String agentArgs, Instrumentation inst)
          {
              final java.io.PrintStream out = System.out;
              inst.addTransformer(new ClassFileTransformer() {
                  public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
      
                      String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
                      out.println(className + " loaded by " + loader + " at " + new java.util.Date() + " in " + pd);
      
                      // dump stack trace of the thread loading class
                      Thread.dumpStack();
      
                      // we just want the original .class bytes to be loaded!
                      // we are not instrumenting it...
                      return null;
                  }
              });
          }
      }
      
      public class MyClass{
             private static  Handler mHandler = new Handler();
             public static int num = 0;
      }
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          //test code start
          new Thread(new Runnable() {
              @Override
              public void run() {
                  try {
                      MyClass myClass = new MyClass();
                  } catch (Throwable e) {
                      e.printStackTrace();
                  }
              }
          }).start();
      
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          MyClass.num = 3;
          // end of test code
      }
      
      private static Handler mHandler;
      private static HandlerThread handlerThread = new HandlerThread("newthread");
      static {
          handlerThread.start();
          mHandler = new Handler(handlerThread.getLooper(), mHandlerCB);
      }
      
      dexOptions {
          preDexLibraries = false
      }
      
       MultiDex.install(this);
      
       @Override
        protected void attachBaseContext(Context base) {
           super.attachBaseContext(base);
           MultiDex.install(this);
        }
      
      // To support MultiDex
      implementation 'com.android.support:multidex:1.0.1'
      
      public class MyApp extends MultiDexApplication {
      
      java.lang.NoClassDefFoundError: com/abc/def/foo/xyz/Iottt
      
      <dependency>
          <groupId>com.abc.def</groupId>
          <artifactId>foo</artifactId>
          <scope>test</scope>
      </dependency>
      
      distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
      
      java -classpath "./dialer.jar" com.company.dialer.DialerServer
      
      java -classpath "./libs/phone.jar;./libs/anotherlib.jar;./dialer.jar" com.company.dialer.DialerServer
      
      Manifest-Version: 1.0
      Class-Path: phone.jar anotherlib.jar
      Build-Jdk-Spec: 1.8
      Main-Class: com.company.dialer.DialerServer
      
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
              <archive>
                  <manifest>
                      <addClasspath>true</addClasspath>
                      <mainClass>com.company.dialer.DialerServer</mainClass>
                  </manifest>
              </archive>
          </configuration>
      </plugin>
      
      java -classpath ./libs/phone.jar:./libs/anotherlib.jar:./dialer.jar
      com.company.dialer.DialerServer