Вопрос-ответ

How can I solve "java.lang.NoClassDefFoundError"?

Как я могу решить "java.lang.NoClassDefFoundError"?

Я пробовал оба примера из руководств Oracle по Java. Они оба отлично компилируются, но во время выполнения оба выдают эту ошибку:

Exception in thread "main" java.lang.NoClassDefFoundError: graphics/shapes/Square
at Main.main(Main.java:7)
Caused by: java.lang.ClassNotFoundException: graphics.shapes.Square
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:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

Я думаю, что у меня может быть Main.java файл не в той папке.

Вот иерархия каталогов:

graphics
├ Main.java
├ shapes
| ├ Square.java
| ├ Triangle.java
├ linepoint
| ├ Line.java
| ├ Point.java
├ spaceobjects
| ├ Cube.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

Я не использовал Eclipse (только Notepad ++ и JDK), и вышеупомянутое обновление решило мою проблему. Однако, похоже, что многие из этих ответов относятся к Eclipse и IntelliJ IDEA, но у них схожие концепции.

Переведено автоматически
Ответ 1

После компиляции вашего кода вы получаете .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. Современные IDE, такие как Eclipse и IntelliJ IDEA, а также инструменты управления сборкой, такие как Maven или Gradle, помогут вам не беспокоиться о путях к классам (как следует) и сосредоточиться на коде! Тем не менее, эта ссылка объясняет, как задать путь к классу при выполнении в командной строке.

Ответ 2

Я хотел бы исправить точку зрения других на NoClassDefFoundError.

NoClassDefFoundError может возникать по нескольким причинам, таким как:


  1. ClassNotFoundException -- .class не найден для этого класса, на который ссылается класс, независимо от того, доступен он во время компиляции или нет (т.е. базовый / дочерний класс).

  2. Файл класса найден, но при инициализации статических переменных возникло исключение

  3. Файл класса найден, исключение возникло при инициализации статических блоков

В исходном вопросе это был первый случай, который можно исправить, установив CLASSPATH для файла JAR classes, на который ссылаются, или для его папки пакета.

Что означает выражение "доступно во время компиляции"?


  • В коде используется класс, на который дана ссылка.
    Например, два класса, A и B (расширяет A). Если ссылка на B содержится непосредственно в коде, она доступна во время компиляции, т.Е., A a = new B();

Что означает "недоступно во время компиляции"?


  • Класс времени компиляции и класс среды выполнения различны, т. Е., Например, базовый класс загружается с использованием classname дочернего класса, например Class.forName ("имя_класса"), например: два класса, A и B (расширяет A). Код имеет

    A a = Class.forName("B").newInstance();

Ответ 3

Если вы получили одну из этих ошибок при компиляции и запуске:


  • NoClassDefFoundError



  • Ошибка: не удалось найти или загрузить основной класс hello



  • Исключение в потоке "main" java.lang.NoClassDefFoundError: javaTest / test / hello (неправильное название: test / hello)


    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$100(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)


-------------------------- Решение -----------------------

Проблема в основном в организации пакетов. Вы должны правильно расположить свои классы по папкам в соответствии с классификацией пакетов в вашем исходном коде.

В процессе компиляции используйте эту команду:

javac -d . [FileName.java]

Чтобы запустить класс, пожалуйста, используйте эту команду:

java [Package].[ClassName]
Ответ 4

Одной из возможных причин этого NoClassDefFoundError может быть то, что класс присутствует в classpath по адресу Compile time, но его нет в classpath по адресу Runtime.

Если вы используете Eclipse, убедитесь, что у вас есть записи shapes, linepoints и spaceobjects as в .classpath файле.

java exception