Как исправить «NoClassDefFoundError» для пакета внутри пакета

#java #package #dependencies #noclassdeffounderror

Вопрос:

Java-программа

Расположение файла : ..new1packageEGB.java

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

Расположение файла : ..new1C.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
 

Пожалуйста, помогите мне, как исправить эту ошибку.

Комментарии:

1. Есть ли у вас все эти классы в одном модуле? Можно ли поделиться проектом репродуктора ?

2. Я упоминал расположение файла перед каждым фрагментом кода, для простоты я добавил представление папок. Надеюсь, это может помочь.

Ответ №1:

Простым решением вашей проблемы будет реструктуризация ваших каталогов. Рекомендуется хранить исходные файлы и классы в отдельных каталогах, обычно «src» и «классы». Затем скомпилируйте с помощью --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 или»; » в Windows.
Линукс:

 java -cp .:./classes A
 

Windows:

 java -cp .;d:pathtodirectoryclasses A