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

голоса
379

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

Задан 29/08/2008 в 15:59
источник пользователем
На других языках...                            


18 ответов

голоса
596

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

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

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

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

Ответил 22/04/2011 d 16:28
источник пользователем

голоса
193

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

Ответил 29/08/2008 d 16:01
источник пользователем

голоса
76

Вот код для иллюстрации 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;
}
Ответил 13/02/2015 d 19:20
источник пользователем

голоса
27

Я обнаружил, что иногда я получаю ошибку NoClassDefFound при компиляции коды с несовместимой версией класса, найденным во время выполнения. Конкретный экземпляр я помню это с библиотекой оси апача. Было фактически две версии на мое время выполнения и классах было собирание УСТАРЕВШЕГО и несовместимой версии и не тот, что вызывает ошибку NoClassDefFound. Это было в приложение командной строки, где я использовал команду, подобную этой.

set classpath=%classpath%;axis.jar

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

set classpath=axis.jar;%classpath%;
Ответил 29/08/2008 d 16:06
источник пользователем

голоса
25

NoClassDefFoundError В Java

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

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

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

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

Примеры:

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

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

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

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

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

Ресурсы:

3 способа решения NoClassDefFoundError

шаблоны java.lang.NoClassDefFoundError Проблемные

Ответил 10/08/2016 d 17:16
источник пользователем

голоса
4

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

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

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

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

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

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

Ответил 15/09/2015 d 18:44
источник пользователем

голоса
4

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

Запустите программу "Java -javaagent: tracer.jar [ВАША ява ARGS]

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

// 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;
            }
        });
    }
}
Ответил 09/09/2015 d 12:02
источник пользователем

голоса
4

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

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

Весна не давала мне полную трассировку стеки , на котором выравнивают выполнения не удались. Он просто сказал NoClassDefFoundError. Но когда я запускал его как родное приложение Java (вынимая его из MVC), это дало ExceptionInInitializerErrorчто было истинной причиной , а что , как я проследил ошибку.

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

Ответил 10/08/2015 d 08:16
источник пользователем

голоса
2

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

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

Ответил 07/11/2016 d 14:03
источник пользователем

голоса
2

Техник ниже помог мне много раз:

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

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

Ответил 27/07/2016 d 13:44
источник пользователем

голоса
0

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

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

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

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


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

mvn clean install -DskipTests

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

mvn test
Ответил 01/04/2018 d 19:09
источник пользователем

голоса
0

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

dexOptions {
        preDexLibraries true
        ...
Ответил 05/02/2018 d 02:34
источник пользователем

голоса
0

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

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

Ответил 29/11/2017 d 12:51
источник пользователем

голоса
0

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

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

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

Ответил 25/10/2017 d 06:58
источник пользователем

голоса
0

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

Ответил 19/06/2017 d 13:48
источник пользователем

голоса
0

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

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

Например,

private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");
Ответил 14/07/2016 d 19:46
источник пользователем

голоса
-5

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

android {
    compileSdkVersion 23
    buildToolsVersion '22.0.1'
    packagingOptions {
    }

    defaultConfig {
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 11
        versionName "2.1"
    }
Ответил 26/04/2016 d 16:40
источник пользователем

голоса
-5

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

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

Ответил 14/10/2015 d 10:19
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more