如何修复包内包的“NoClassDefFoundError”

问题描述

Java 程序

文件位置:..\new1\packageEG\B.java

package packageEG ;
public class B
{
    public void display()
    {
        System.out.println("B") ;
    }
}

文件位置:..\new1\C.java

package new1 ;
import packageEG.B ;
public class C 
{
    public void display()
    {
        B b = new B() ;
        b.display() ;
    }
}

文件位置:..\A.java

import new1.C ;
public class A 
{
    public static void main(String[] args)
    {
        C c = new C() ;
        c.display() ;
    }
} 

文件夹视图

../
   A.java
   new1/
      C.java
      packageEG/
            B.java 

它有嵌套包,一个包在另一个包中。

当我编译主类,即“A”时,它编译成功,但是当我运行这个程序时,它显示以下错误

Exception in thread "main" java.lang.NoClassDefFoundError: packageEG/B
        at new1.C.display(C.java:7)
        at A.main(A.java:7)
Caused by: java.lang.classNotFoundException: packageEG.B
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
        at java.base/java.lang.classLoader.loadClass(ClassLoader.java:522)
        ... 2 more

请帮我解决这个错误

解决方法

解决您的问题的一个简单方法是重组您的目录。将源文件和类存储在单独的目录中是一种很好的做法,通常是“src”和“classes”。然后使用 --class-path 选项编译。

以您的情况为例,我们可以将您的项目结构视为(我们也可以将 A.java 放在 src 目录中,但为了与您的代码结构保持一些相似性,让我们考虑一下):

tree
.
├── A.java
└── src
    └── com
        └── xyz
            ├── B.java
            └── C.java

要使用JDK编译源代码,我们需要使用-d选项指定编译类的基目录,即classes,如下:

javac -d classes src/com/xyz/B.java src/com/xyz/C.java

现在使用 A.java-cp 选项编译 --class-path 以指定包 com.xyz 的基目录以定位 com.xyz.C

javac -cp ./classes/ A.java

现在目录结构如下:

tree
.
├── A.class
├── A.java
├── classes
│   └── com
│       └── xyz
│           ├── B.class
│           └── C.class
└── src
    └── com
        └── xyz
            ├── B.java
            └── C.java

要运行,显式设置 CLASSPATH 变量以在 CLASSPATH 中包含当前目录(使用 '.' 表示)以及包 com.xyz 的基本目录,以 ':' 分隔linux 或 ';'在窗户上。 Linux:

java -cp .:./classes A

视窗:

java -cp .;d:\path\to\directory\classes A