Как решить java.ленг.Ошибке типа 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.run(URLClassLoader.java:366)
    at java.net.URLClassLoader.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; к нему), установите classpath в " _test "(папка, содержащая графику), скомпилировал его и запустил с помощью java graphics.Main (из командной строки), он работал.

действительно позднее обновление #2

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

23 ответов


после компиляции кода Вы получаете .class файлы для каждого класса в вашей программе. Эти двоичные файлы являются байт-кодом, который Java интерпретирует для выполнения вашей программы. The NoClassDefFoundError указывает, что classloader (в этом случае java.net.URLClassLoader), которая отвечает за динамическую загрузку классов, не может найти для класса, который вы пытаетесь использовать.

ваш код не будет компилироваться, если необходимые классы не присутствуют (если классы не загружены с отражение), поэтому обычно это исключение означает, что ваш путь к классам не включает требуемые классы. Помните, что classloader (в частности java.net.URLClassLoader) будет искать классы в пакете a.b.c в папке a/b/ c / в каждой записи в пути к классам. NoClassDefFoundError также может указывать на отсутствие транзитивной зависимости a .jar-файл, который вы скомпилировали и пытаетесь использовать.

например, если у вас был класс com.example.Foo, после компиляции у вас будет файл класса Foo.class. Скажем, например, ваш рабочий каталог .../project/. Этот файл класса должен быть помещен в .../project/com/example, и вы установили бы свой путь к классам в .../project/.

примечание: Я бы рекомендовал воспользоваться удивительным инструментарием, который существует для языков Java и JVM. Современные IDE, такие как Eclipse и IDEA, и инструменты управления сборкой, такие как Maven или Gradle, помогут вам не беспокоиться о путях классов (столько же) и сосредоточиться на коде! Что сказал:этой ссылке объясняет, как установить classpath при выполнении в командной строке.


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

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

  1. -- ClassNotFoundException .класс не найден для этого ссылочного класса независимо от того, доступен ли он во время компиляции или нет(i.e базовый / дочерний класс).
  2. файл класса находится, но исключение возникает при инициализации статических переменных
  3. класса, расположенный, исключение повышено, инициализация статических блоков

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

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

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

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

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

NoClassDefFoundError означает, что класс присутствует в classpath в Compile time, но он не существует в classpath в Runtime.

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


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

  • ошибке типа noclassdeffounderror

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

  • исключение в потоке" main " java.ленг.NoClassDefFoundError: javaTest / тест / Здравствуйте ( неправильное имя: test / hello) на Яве.ленг.загрузчик классов.defineClass1(родной способ) на Яве.ленг.загрузчик классов.defineClass(неизвестный источник) на Ява.безопасность.SecureClassLoader.defineClass(неизвестный источник) в Java.чистая.Urlclassloader, на.defineClass(неизвестный источник) в Java.чистая.Urlclassloader, на.доступ к$100(неизвестный источник) на Яве.сеть.URLClassLoader$1.выполнить (неизвестный источник) на Яве.сеть.URLClassLoader$1.выполнить (неизвестный источник) на Яве.безопасность.AccessController.doPrivileged(Native метод) в Java.чистая.Urlclassloader, на.findClass(неизвестный источник) на Яве.ленг.загрузчик классов.loadClass(неизвестный источник) на солнце.разное.Launcher$AppClassLoader.loadClass(неизвестный источник) на Яве.ленг.загрузчик классов.loadClass(неизвестный источник) в Sun.пусковая установка.LauncherHelper.checkAndLoadMain (неизвестный источник)

-------------------------- SOLUTIION -----------------------

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

On Compiling process use this command:

javac -d . [FileName.java]

To Run the class please use this command:

java [Package].[ClassName]

java.lang.NoClassDefFoundError

указывает, что что-то нашли в compiletime а не время работы. возможно, Вам просто нужно добавить его в classpath.


Нет Исключения Определения Класса происходит, когда предполагаемый класс не найден в пути к классу. Во время компиляции Class: Class был сгенерирован из компилятора Java, но как-то во время выполнения зависимый класс не найден.

давайте рассмотрим один простой пример:

public class ClassA{
public static void main(String args[]){
     //Some gibberish Code...
     String text = ClassB.getString();
     System.out.println("Text is :" + text);
}

}

public class ClassB{
    public static String getString(){
      return "Testing Some Exception";
 }
}

теперь предположим, что вышеупомянутые два исходного кода Java помещены в некоторую папку, скажем, "NoClassDefinationFoundExceptionDemo"

теперь откройте оболочку (при условии, что Java уже настроен правильно)

  1. перейдите в папку "NoClassDefinationFoundExceptionDemo"
  2. Компиляция Исходных Файлов Java когда javac то и javac класса
  3. оба файла компилируются успешно и генерируются файлы классов в одной папке как класса classa.класс и ClassB.класс!--16-->
  4. теперь, так как мы превышаем ClassPath до текущего рабочего каталога поэтому мы выполняем следующую команду java -панель управления. Класса classa и это сработало успешно, и вы увидите вывод на экране
  5. теперь скажем, вы удалили ClassB.файл класса из текущего каталога. и теперь вы выполняете команду снова. java-cp . Класса classa теперь он будет приветствовать вас с NoClassDefFoundException. а то что зависимость для classa не нашли в classpath(я.е текущего рабочего каталога).

NoClassDefFoundError в Java:

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

NoClassDefFoundError появится, если класс присутствовал во время компиляции, но недоступен в Java classpath во время выполнения. Обычно вы увидите ниже строку в журнале, когда вы получаете NoClassDefFoundError: Исключение в потоке" main " java.ленг.Ошибке типа noclassdeffounderror

Возможные Причины:

  1. класс недоступен в Java Путь класса.

  2. вы можете запускать свою программу с помощью команды jar, А класс не был определен в атрибуте ClassPath файла манифеста.

  3. любой сценарий запуска переопределяет переменную среды Classpath.

  4. потому что NoClassDefFoundError является подклассом java.ленг.LinkageError он также может прийти, если одна из его зависимостей, таких как собственная библиотека, может быть недоступна.

  5. проверить Ява.ленг.ExceptionInInitializerError в вашем файле журнала. NoClassDefFoundError из-за сбоя статической инициализации довольно распространен.

  6. Если вы работаете в среде J2EE, то видимость класса среди нескольких загрузчиков классов также может вызвать java.ленг.Noclassdeffounderror, см. примеры и раздел сценария для подробного обсуждения.

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

  1. убедитесь, что все требуется Java-классов включены в classpath приложения. Самая распространенная ошибка-не включать все необходимые классы перед началом выполнения приложения Java, которое имеет зависимости от некоторых внешних библиотек.

  2. путь к классам приложения является правильным, но переменная среды пути к классам переопределяется перед выполнением приложения.

  3. убедитесь, что вышеупомянутый ExceptionInInitializerError делает не отображается в трассировке стека приложения.

ресурсы:

3 способа решения java.ленг.NoClassDefFoundError в Java J2EE

java.ленг.NoClassDefFoundError – как решить ошибку класса Def не найдено


если ваш проект находится в пакете, как com.blahcode и ваш класс называется Main, скомпилированные файлы могут быть выведены в структуру каталогов, как ./out/com/blahcode/Main.class. Особенно это касается идеи IntelliJ.

при попытке запуска из оболочки или cmd вам нужно cd к тому, что содержит com как подкаталог.

cd out
java -classpath . com.blahcode.Main

я столкнулся с проблемой сегодня. У меня есть проект Android и после включения multidex проект больше не начнется.

причина заключалась в том, что я забыл вызвать конкретный многодексный метод, который должен быть добавлен в Application class и вызывается прежде всего.

 MultiDex.install(this);

следуйте этому руководству, чтобы правильно включить multidex. https://developer.android.com/studio/build/multidex.html

вы должны добавить эти строки ваш класс приложений

 @Override
  protected void attachBaseContext(Context base) {
     super.attachBaseContext(base);
     MultiDex.install(this);
  }

после работы над проектом NetBeans в течение многих месяцев я внезапно получил сообщение NoClassDefFoundError вскоре после получения предупреждения "низкая память". Выполнение чистой перестройки не помогло, но закрытие Netbeans вообще и повторное открытие проекта не было отчетов об ошибках.


этот ответ специфичен для java.ленг.NoClassDefFoundError происходит в сервис:

моя команда недавно увидела эту ошибку после обновления rpm, который предоставил услугу. Rpm и программное обеспечение внутри него были построены с Maven, поэтому казалось, что у нас была зависимость времени компиляции, которая просто не была включена в rpm.

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

возможное решение: перезапустить службу!

похоже, что обновление rpm аннулировало дескриптор файла службы в базовом файле jar. Затем служба увидела класс, который не был загружен в память, искала его среди списка дескрипторов файлов jar и не смогла найти это потому, что дескриптор файла, из которого он мог загрузить класс, был признан недействительным. Перезапуск службы заставил его перезагрузить все дескрипторы файлов, что позволило ему загрузить класс, который не был найден в памяти сразу после обновления rpm.

надеемся, что конкретный случай поможет кому-то.


мои два цента в этой цепочке:

обеспечить classpath содержит полное дорожки (/home/user/lib/some_lib.jar вместо ~/lib/some_lib.jar) в противном случае вы все равно можете столкнуться NoClassDefFoundError ошибка.


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

запустите программу с помощью ' 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;
            }
        });
    }
}

это происходит много с моими устройствами genymotion. Убедитесь, что на вашем диске, где установлен Genymotion, имеется хороший объем памяти.


Это случилось со мной в Android Studio.

решение, которое сработало для меня: просто перезапустите студию.


У меня была такая же проблема с моей разработкой Android с помощью Android studio. Предлагаемые решения являются общими и не помогли мне ( по крайней мере, для меня). После нескольких часов исследований я нашел следующее решение и может помочь разработчикам android, которые занимаются разработкой с помощью android studio. измените настройку, как показано ниже Настройки - >сборка, выполнение, развертывание -> Instant Run -> un-проверьте первый вариант.

с этим изменением я встаю и бегу. Надеюсь, это поможет моему dev друзья.


Если вы используете более одного модуля, вы должны иметь

dexOptions { preDexLibraries = false }

в файле build.


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

-libraryJars "путь.на.a.пропал.банку.библиотека".

Это объясняет, почему компиляция и запуск работают нормально, учитывая, что jar есть, в то время как clean & build терпит неудачу. Не забудьте определить недавно добавленные библиотеки jar в настройке proguard!

обратите внимание, что сообщения об ошибках от Proguard действительно не соответствуют стандарту, так как их легко спутать с подобные муравьиные сообщения поступают, когда банки вообще нет. Только в самом низу будет небольшая подсказка программы ProGuard в беде. Следовательно, вполне логично начать поиск традиционных ошибок, классов и т. д., Но это будет напрасно.

очевидно, исключение NoClassDefFound будет результатом при запуске, например, результирующего исполняемого jar, построенного и основанного на отсутствии последовательности proguard. Некоторые называют это proguard "ад"


Я использую плагин FileSync для Eclipse поэтому я могу жить отладкой на Tomcat & я получил NoClassFoundError потому что я добавил запись синхронизации bin каталог в рабочей области Eclipse => classes на metadata для Tomcat, но также не добавил синхронизацию папок для


1) Первый метод: я решил эту проблему, удалив некоторые зависимости класса удалите их из кода ниже этой проблемы, с которой я столкнулся на 4.2.2

compile 'com.google.android.gms:play-services-gcm:11.0.4'
compile 'com.google.android.gms:play-services:11.0.4'

это дополнительные в моем коде, я удалил их

 dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
})
compile files('libs/ypylibs.jar')
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.google.android.gms:play-services-gcm:11.0.4'
compile 'com.google.android.gms:play-services:11.0.4'
compile 'com.google.android.gms:play-services-ads:11.0.4'
compile 'com.dailymotion.dailymotion-sdk-android:sdk:0.1.12'
compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'commons-io:commons-io:1.3.2'
compile 'com.oguzdev:CircularFloatingActionMenu:1.0.2'
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'

} (2) Метод:другой способ решить эту проблему-сделать новый класс Myapplication

public class MyApplication extends Application {

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}

}

затем добавьте его в файл mainfest и в тег приложения

 <application
    android:allowBackup="true"
    android:name=".gps.navigation.map.MyApplication"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"></application>

после этого в вашей основной деятельностью удалить appcompactactivity при необходимости и расширить свой класс с активностью он будет работать тогда.


Я разрабатываю приложение на основе Eclipse, также известное как RCP (богатая клиентская платформа). И я столкнулся с этой проблемой после рефакторинга (перемещение одного класса из плагина в новый).

очистка проекта и обновление Maven не помогли.

проблема была вызвана Bundle-Activator, которые не были автоматически обновлены. Обновление пакета-активатора вручную в разделе манифест.MF в новом плагине есть исправил мою проблему.


Если вы недавно добавили поддержку multidex в Android studio, как это:

// To Support MultiDex
implementation 'com.android.support:multidex:1.0.1'

таким образом, ваше решение просто расширяется от MultiDexApplication вместо Application

public class MyApp extends MultiDexApplication {

проверьте, что если у вас есть статический обработчик в вашем классе, если это так, пожалуйста, будьте осторожны, потому что статический обработчик только может быть инициирован в потоке, который имеет петлитель, сбой может быть вызван таким образом:

1.сначала создайте экземпляр класса в простом потоке и поймайте сбой.

2.затем вызовите метод поля класса в основном потоке, вы получите NoClassDefFoundError.

вот тест код:

public class MyClass{
       private static  Handler mHandler = new Handler();
       public static int num = 0;

}

в БРУ способ основного вида деятельности, добавление тестовый код части:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //test code start
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                MyClass myClass = new MyClass();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }).start();

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    MyClass.num = 3;
    // end of test code
}

есть простой способ исправить это с помощью handlerThread для обработчик init:

private static Handler mHandler;
private static HandlerThread handlerThread = new HandlerThread("newthread");
static {
    handlerThread.start();
    mHandler = new Handler(handlerThread.getLooper(), mHandlerCB);
}