Вопрос:

Почему я получаю NoClassDefFoundError в Java?

java noclassdeffounderror

659869 просмотра

21 ответа

12762 Репутация автора

Я получаю, NoClassDefFoundErrorкогда я запускаю свое Java-приложение. Что обычно является причиной этого?

Автор: John Meagher Источник Размещён: 29.08.2008 02:59

Ответы (21)


236 плюса

5724 Репутация автора

Решение

Это происходит, когда существует файл класса, от которого зависит ваш код, и он присутствует во время компиляции, но не найден во время выполнения. Ищите различия во времени сборки и во время выполнения классов.

Автор: Mocky Размещён: 29.08.2008 03:01

31 плюса

16754 Репутация автора

Я обнаружил, что иногда я получаю ошибку NoClassDefFound, когда код компилируется с несовместимой версией класса, найденной во время выполнения. Конкретный экземпляр, который я помню, связан с библиотекой оси Apache На моем пути к классам во время выполнения на самом деле было две версии, и он выбирал устаревшую и несовместимую версию, а не правильную, вызывая ошибку NoClassDefFound. Это было в приложении командной строки, где я использовал команду, подобную этой.

set classpath=%classpath%;axis.jar

Я смог заставить его подобрать правильную версию, используя:

set classpath=axis.jar;%classpath%;
Автор: shsteimer Размещён: 29.08.2008 03:06

729 плюса

17394 Репутация автора

Хотя возможно, что это связано с несоответствием пути к классам между временем компиляции и временем выполнения, это не всегда так.

В этом случае важно сохранить два или три разных исключения в нашей голове:

  1. java.lang.ClassNotFoundException Это исключение указывает, что класс не был найден в пути к классам. Это указывает на то, что мы пытались загрузить определение класса, а класс не существовал в пути к классам.

  2. java.lang.NoClassDefFoundError Это исключение указывает на то, что JVM искала в своей внутренней структуре данных определения класса определение класса и не нашла его. Это отличается от того, что он не может быть загружен из пути к классам. Обычно это указывает на то, что мы ранее пытались загрузить класс из пути к классам, но по какой-то причине это не удалось - теперь мы пытаемся использовать класс снова (и, следовательно, нужно загрузить его, так как в прошлый раз он не удался), но мы мы даже не собираемся пытаться загрузить его, потому что мы не смогли загрузить его раньше (и разумно подозреваем, что у нас снова получится ошибка). Более ранний сбой мог быть ClassNotFoundException или ExceptionInInitializerError (указывающий на сбой в блоке статической инициализации) или любым другим количеством проблем. Дело в том, что NoClassDefFoundError не обязательно является проблемой пути к классам.

Автор: Jared Размещён: 22.04.2011 03:28

107 плюса

1804 Репутация автора

Вот код для иллюстрации java.lang.NoClassDefFoundError. Пожалуйста, смотрите ответ Джареда для подробного объяснения.

NoClassDefFoundErrorDemo.java

public class NoClassDefFoundErrorDemo {
    public static void main(String[] args) {
        try {
            // The following line would throw ExceptionInInitializerError
            SimpleCalculator calculator1 = new SimpleCalculator();
        } catch (Throwable t) {
            System.out.println(t);
        }
        // The following line would cause NoClassDefFoundError
        SimpleCalculator calculator2 = new SimpleCalculator();
    }

}

SimpleCalculator.java

public class SimpleCalculator {
    static int undefined = 1 / 0;
}
Автор: xli Размещён: 13.02.2015 07:20

6 плюса

1449 Репутация автора

Я использовал Spring Framework с Maven и решил эту ошибку в своем проекте.

В классе произошла ошибка во время выполнения. Я читал свойство как целое число, но когда оно прочитало значение из файла свойств, его значение было двойным.

Spring не дал мне полную трассировку стека, на какой линии произошла ошибка во время выполнения. Это просто сказано NoClassDefFoundError. Но когда я выполнил его как нативное Java-приложение (взяв его из MVC), оно дало информацию, ExceptionInInitializerErrorкоторая была истинной причиной и как я отследил ошибку.

Ответ @ xli дал мне понимание того, что может быть не так в моем коде.

Автор: Nikhil Sahu Размещён: 10.08.2015 08:16

5 плюса

1032 Репутация автора

Я получаю NoClassFoundError, когда классы, загруженные загрузчиком классов среды выполнения, не могут получить доступ к классам, уже загруженным загрузчиком Java. Поскольку разные загрузчики классов находятся в разных доменах безопасности (согласно java), jvm не позволит разрешить классы, уже загруженные корневым загрузчиком, в адресном пространстве загрузчика времени выполнения.

Запустите вашу программу с помощью «java -javaagent: tracer.jar [ВАШИ java ARGS]»

Он производит вывод, показывающий загруженный класс, и загрузчик env, который загрузил класс. Очень полезно отслеживать, почему класс не может быть решен.

// 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;
            }
        });
    }
}
Автор: codeDr Размещён: 09.09.2015 12:02

7 плюса

10889 Репутация автора

Это лучшее решение, которое я нашел до сих пор.

Предположим, у нас есть пакет, org.mypackageсодержащий классы:

  • HelloWorld (основной класс)
  • SupportClass
  • UtilClass

и файлы, определяющие этот пакет, хранятся физически в каталоге D:\myprogram(в Windows) или /home/user/myprogram(в Linux).

Структура файла будет выглядеть так: введите описание изображения здесь

Когда мы вызываем Java, мы указываем имя приложения для запуска: org.mypackage.HelloWorld. Однако мы также должны указать Java, где искать файлы и каталоги, определяющие наш пакет. Итак, чтобы запустить программу, мы должны использовать следующую команду: введите описание изображения здесь

Автор: Ram Patra Размещён: 15.09.2015 06:44

-6 плюса

34 Репутация автора

Я получил это сообщение после удаления двух файлов из библиотеки SRC, и когда я возвращал их, я продолжал видеть это сообщение об ошибке.

Мое решение было: перезапустите Eclipse. С тех пор я больше не видел это сообщение :-)

Автор: Eliran Размещён: 14.10.2015 10:19

-7 плюса

25 Репутация автора

Убедитесь, что это соответствует в module:appи module:lib:

android {
    compileSdkVersion 23
    buildToolsVersion '22.0.1'
    packagingOptions {
    }

    defaultConfig {
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 11
        versionName "2.1"
    }
Автор: Alex Размещён: 26.04.2016 04:40

-1 плюса

690 Репутация автора

У меня была такая же проблема, и я был на складе в течение многих часов.

Я нашел решение. В моем случае был определен статический метод. JVM не может создать другой объект этого класса.

Например,

private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");
Автор: sudar Размещён: 14.07.2016 07:46

2 плюса

1313 Репутация автора

Методика ниже помогла мне много раз:

System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());

где TheNoDefFoundClass - это класс, который может быть «потерян» из-за предпочтения более старой версии той же библиотеки, что и ваша программа. Чаще всего это происходит в тех случаях, когда клиентское программное обеспечение развертывается в доминирующем контейнере, оснащенном собственными загрузчиками классов и множеством древних версий самых популярных библиотек.

Автор: Aram Paronikyan Размещён: 27.07.2016 01:44

30 плюса

1670 Репутация автора

NoClassDefFoundError в Java

Определение:

  1. Виртуальная машина Java не может найти определенный класс во время выполнения, который был доступен во время компиляции.

  2. Если класс присутствовал во время компиляции, но не был доступен в java classpath во время выполнения.

введите описание изображения здесь

Примеры:

  1. Класс не находится в Classpath, нет точного способа узнать его, но много раз вы можете просто посмотреть, как распечатать System.getproperty ("java.classpath"), и он напечатает classpath оттуда, по крайней мере, вы можете получить идея вашего фактического пути к классам во время выполнения.
  2. Простой пример NoClassDefFoundError - класс принадлежит отсутствующему файлу JAR, или JAR не был добавлен в classpath, или иногда имя jar было изменено кем-то, как в моем случае один из моих коллег изменил tibco.jar на tibco_v3.jar, и программа не удалось с java.lang.NoClassDefFoundError, и мне было интересно, что не так.

  3. Просто попробуйте запустить с явным параметром -classpath с classpath, который, по вашему мнению, будет работать, и если он работает, это верный короткий признак того, что кто-то переопределяет java classpath.

  4. Проблема с правами доступа к файлу JAR также может вызвать NoClassDefFoundError в Java.
  5. Опечатка в XML-конфигурации также может вызвать NoClassDefFoundError в Java.
  6. когда ваш скомпилированный класс, который определен в пакете, не присутствует в том же пакете во время загрузки, как в случае с JApplet, он выдаст NoClassDefFoundError в Java.

Возможные решения:

  1. Класс недоступен в Java Classpath.
  2. Если вы работаете в среде J2EE, то видимость Class среди нескольких Classloader также может вызвать java.lang.NoClassDefFoundError, подробное обсуждение см. В разделе примеров и сценариев.
  3. Проверьте наличие java.lang.ExceptionInInitializerError в файле журнала. NoClassDefFoundError из-за сбоя статической инициализации встречается довольно часто.
  4. Поскольку NoClassDefFoundError является подклассом java.lang.LinkageError, он также может появиться, если одна из его зависимостей, такая как нативная библиотека, может быть недоступна.
  5. Любой сценарий запуска переопределяет переменную среды Classpath.
  6. Возможно, вы запускаете программу с помощью команды jar, а класс не определен в атрибуте ClassPath файла манифеста.

Ресурсы:

3 способа решить NoClassDefFoundError

java.lang.NoClassDefFoundError Образцы проблем

Автор: Virtual Размещён: 10.08.2016 05:16

3 плюса

646 Репутация автора

В случае, если вы сгенерировали код (EMF и т. Д.), Может быть слишком много статических инициализаторов, которые занимают все пространство стека.

См. Вопрос переполнения стека. Как увеличить размер стека Java? ,

Автор: Aykut Kllic Размещён: 07.11.2016 02:03

0 плюса

1101 Репутация автора

Если кто-то приходит сюда из-за java.lang.NoClassDefFoundError: org/apache/log4j/Loggerошибки, в моем случае это было вызвано тем, что я использовал log4j 2 (но я не добавил все файлы, которые идут с ним), а некоторая библиотека зависимостей использовала log4j 1. Решением было добавить Log4j. 1.x bridge: jar, log4j-1.2-api-<version>.jarкоторый поставляется с log4j 2. Больше информации в log4j 2 миграции .

Автор: ST7 Размещён: 19.06.2017 01:48

0 плюса

606 Репутация автора

Две разные кассовые копии одного и того же проекта

В моем случае проблема заключалась в неспособности Eclipse различать две разные копии одного и того же проекта. У меня один заблокирован на транке (контроль версий SVN), а другой работает в одной ветви одновременно. Я опробовал одно изменение в рабочей копии как тестовый пример JUnit, который включал в себя извлечение частного внутреннего класса в открытый класс, и пока он работал, я открываю другую копию проекта, чтобы посмотреть на некоторые другие часть кода, которая нуждалась в изменениях. В какой-то момент NoClassDefFoundErrorвсплыли жалобы на то, что частного внутреннего класса там не было; двойной щелчок в трассировке стека привел меня к исходному файлу в неправильной копии проекта.

Закрытие транковой копии проекта и запуск тестового примера снова избавили от проблемы.

Автор: manuelvigarcia Размещён: 25.10.2017 06:58

-1 плюса

27 Репутация автора

Java не смог найти класс A во время выполнения. Класс А был в Maven проекте ArtClient из другого рабочего пространства. Поэтому я импортировал ArtClient в свой проект Eclipse. Два моих проекта использовали ArtClient в качестве зависимости. Я изменил ссылку на библиотеку на ссылку проекта для этих (Build Path -> Configure Build Path).

И проблема ушла.

Автор: Pekmezli Dürüm Размещён: 29.11.2017 12:51

1 плюс

538 Репутация автора

Я исправил свою проблему, отключив preDexLibraries для всех модулей:

dexOptions {
        preDexLibraries false
        ...
Автор: Michael Размещён: 05.02.2018 02:34

0 плюса

29005 Репутация автора

Эта ошибка может быть вызвана непроверенными требованиями к версии Java .

В моем случае мне удалось устранить эту ошибку при создании громкого проекта с открытым исходным кодом, переключившись с Java 9 на Java 8 с помощью SDKMAN! ,

sdk list java
sdk install java 8u152-zulu
sdk use java 8u152-zulu

Затем выполните чистую установку, как описано ниже.


При использовании Maven в качестве инструмента сборки иногда полезно - и, как правило, приятно, делать чистую сборку «install» с отключенным тестированием .

mvn clean install -DskipTests

Теперь, когда все собрано и установлено, вы можете продолжить и запустить тесты.

mvn test
Автор: nobar Размещён: 01.04.2018 07:09

1 плюс

1227 Репутация автора

NoClassDefFoundErrorЭто также может произойти, когда статический инициализатор пытается загрузить пакет ресурсов, который недоступен во время выполнения, например файл свойств, который уязвимый класс пытается загрузить из META-INFкаталога, но его там нет. Если вы не поймаете NoClassDefFoundError, иногда вы не сможете увидеть полную трассировку стека; Чтобы преодолеть это, вы можете временно использовать catchпункт для Throwable:

try {
    // Statement(s) that cause the affected class to be loaded
} catch (Throwable t) {
    Logger.getLogger("<logger-name>").info("Loading my class went wrong", t);
}
Автор: ᴠɪɴᴄᴇɴᴛ Размещён: 27.09.2018 08:30

4 плюса

21715 Репутация автора

Прочтите это, особенно если вы видите NoClassDefFoundErrorsв ЕДИНЫХ ТЕСТАХ ...


Один интересный случай, в котором вы можете увидеть много случаев NoClassDefFoundErrors, когда вы:

  1. throwRuntimeExceptionв staticблоке вашего классаExample
  2. Перехватить его (или, если это просто не имеет значения, как если бы его бросили в тестовом примере )
  3. Попробуйте создать экземпляр этого класса Example

static class Example {
    static {
        thisThrowsRuntimeException();
    }
}

static class OuterClazz {

    OuterClazz() {
        try {
            new Example();
        } catch (Throwable ignored) { //simulating catching RuntimeException from static block
            // DO NOT DO THIS IN PRODUCTION CODE, THIS IS JUST AN EXAMPLE in StackOverflow
        }

        new Example(); //this throws NoClassDefFoundError
    }
}

NoClassDefErrorбудет брошен в сопровождении ExceptionInInitializerErrorот статического блока RuntimeException.


Это особенно важно в тех случаях, когда вы видите NoClassDefFoundErrorsв своих ЕДИНИЦАХ ТЕСТЫ .

В некотором смысле вы «разделяете» выполнение staticблока между тестами, но начальная ExceptionInInitializerErrorбудет только в одном тестовом случае. Первый, который использует проблемный Exampleкласс. Другие тестовые случаи, которые используют этот Exampleкласс, просто выбросят NoClassDefFoundErrors.

Автор: Bartek Lipinski Размещён: 04.12.2018 04:04

0 плюса

550 Репутация автора

Я получил ошибки NoClassDefFound, когда не экспортировал класс на вкладке «Порядок и экспорт» в пути сборки Java моего проекта. Обязательно поставьте галочку на вкладке «Заказ и экспорт» всех зависимостей, которые вы добавляете в путь сборки проекта. См. Предупреждение Eclipse: XXXXXXXXXXX.jar не будет экспортирован или опубликован. Runtime ClassNotFoundExceptions может привести .

Автор: Steve Stilson Размещён: 03.04.2019 09:58
Вопросы из категории :
32x32