Process java lang noclassdeffounderror

Ошибка java.lang.NoClassDefFoundError в JUnit

В этой статье мы поймем, почему в JUnit возникает ошибка java.lang.NoClassDefFoundError и как ее исправить. Эта проблема в основном связана с конфигурациями IDE. Поэтому мы сосредоточимся на самых популярных IDE: Visual Studio Code, Eclipse и IntelliJ, чтобы воспроизвести и устранить эту ошибку.

2. Что такое java.lang.NoClassDefFoundError ?​

Когда среда выполнения Java запускает программу Java, она не загружает сразу все классы и зависимости. Вместо этого он вызывает загрузчик классов Java для загрузки классов в память по мере необходимости. При загрузке класса, если загрузчик классов не может найти определение класса, он выдает ошибку NoClassDefFoundError .

Есть несколько причин, по которым Java не может найти определение класса:

  • Отсутствие нескольких зависимых банок, что является наиболее распространенной причиной.
  • Все банки добавляются как зависимости, но по неправильному пути.
  • Несоответствие версий в зависимостях .

3. Код ВС​

Для написания тестовых случаев Junit4 нам требуется jar Junit4. Однако Junit4 имеет внутреннюю зависимость от jar ядра hamcrest .

Если мы пропустим добавление jar hamcrest-core в качестве зависимости в наш путь к классам, Java выдаст ошибку NoClassDefFoundError . Путь к классам выглядит следующим образом:

Еще один сценарий: мы добавили обе банки, но версии не совпадают. Например, если мы добавили JUnit jar версии 4.13.2 и jar версии 2.2 hamcrest-core , выдается NoClassDefFoundError :

./862ff58c14b49a983ebc12f5e8e8a6f4.png

В обоих случаях выводится одна и та же трассировка стека:

 java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing  at java.base/java.lang.ClassLoader.defineClass1(Native Method)  at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1010)  at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)  at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:855)  at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:753)  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:676) 

Чтобы устранить ошибку в обоих сценариях (отсутствующие зависимости и несоответствие версий), нам нужно добавить правильные зависимости. В случае с Junit4 правильными зависимостями являются junit-4.13.2.jar и hamcrest-core-1.3.jar . Добавление этих двух банок в зависимости (ссылочные библиотеки) устраняет ошибку. Инструкции по добавлению и удалению внешних jar-файлов в VS Code присутствуют здесь . Раздел библиотеки, на который мы ссылаемся, должен быть настроен как:

4. Затмение​

В среде Eclipse IDE, которая поддерживает Java 9 и выше, у нас есть путь к классам и путь к модулю. Чтобы разрешить зависимость модуля, мы используем путь к модулю. Однако добавление внешних jar-файлов в путь к модулю не делает их доступными для загрузчика классов . Следовательно, загрузчик классов считает их отсутствующими зависимостями и выдает ошибку NoClassDefFoundError .

Следовательно, если наша зависимость выглядит так, как показано на изображении ниже, выполнение тестового примера Junit приводит к NoClassDefFoundError:

./59b911c40f6cd58786077157e86e4723.png

Трассировка стека, сгенерированная при выполнении теста JUnit, выглядит следующим образом:

 java.lang.NoClassDefFoundError: org/junit/runner/manipulation/Filter  at java.base/java.lang.Class.forName0(Native Method)  at java.base/java.lang.Class.forName(Class.java:377)  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadTestLoaderClass(RemoteTestRunner.java:381) 

В Eclipse нам нужно добавить jar-файлы в путь к классам, а не в путь к модулю. Итак, чтобы правильно добавить внешние банки, следуйте по пути:

щелкните правой кнопкой мыши проект — > Путь сборки — > Настроить путь сборки

В открывшемся окне удалите банки из-под пути к модулю и добавьте их в путь к классам. Это устраняет NoClassDefFoundError . Правильный путь к классам для запуска JUnit должен быть похож на:

./c23dc5d91eb7b5c7b56ea39daefe2505.png

5. Интеллидж​

Для запуска тестовых случаев JUnit 5 требуется как механизм Jupiter, так и API Jupiter. Механизм Jupiter внутренне зависит от API Jupiter, поэтому в большинстве случаев достаточно добавить только зависимость механизма Jupiter в pom.xml. Однако добавление только зависимости API Jupiter в наш pom.xml и отсутствие зависимости механизма Jupiter приводит к NoClassDefFoundError .

Неправильная настройка в pom.xml будет выглядеть так:

 dependencies>   dependency>   groupId>org.junit.jupitergroupId>   artifactId>junit-jupiter-apiartifactId>   version>5.8.1version>   scope>testscope>   dependency>   dependencies> 

Запуск простого тестового примера с этой настройкой приводит к следующей трассировке стека:

 Exception in thread "main" java.lang.NoClassDefFoundError: org/junit/platform/engine/TestDescriptor  at java.base/java.lang.Class.forName0(Native Method)  at java.base/java.lang.Class.forName(Class.java:375)  at com.intellij.rt.junit.JUnitStarter.getAgentClass(JUnitStarter.java:230) .  

В IntelliJ для исправления зависимостей нам нужно исправить pom.xml . Исправленный pom.xml выглядит так:

 dependencies>   dependency>   groupId>org.junit.jupitergroupId>   artifactId>junit-jupiter-apiartifactId>   version>5.8.1version>   scope>testscope>   dependency>   dependency>   groupId>org.junit.jupitergroupId>   artifactId>junit-jupiter-engineartifactId>   version>5.8.1version>   scope>testscope>   dependency>   dependencies> 

В качестве альтернативы мы можем добавить junit-jupiter-engine, поскольку его добавление автоматически добавляет jar junit-jupiter-api в путь к классам и устраняет ошибку.

6. Резюме​

В этой статье мы рассмотрели различные причины возникновения ошибки java.lang.NoClassDefFoundError в JUnit. Мы также видели, как мы устраняем ошибку в разных IDE. Весь код этого руководства доступен на GitHub .

Источник

How to Resolve the NoClassDefFoundError in Java

How to Resolve the NoClassDefFoundError in Java

The NoClassDefFoundError is a runtime error in Java that occurs if the Java Virtual Machine (JVM) or a ClassLoader instance attempts to load the definition of a class that could not be found. The class definition exists at compile-time but is not available at runtime.

What Causes NoClassDefFoundError

The NoClassDefFoundError occurs in Java when the JVM is unable to find a particular class at runtime which was available at compile-time.

The definition of the class is attempted to be loaded as part of a normal method call or creating an instance of the class using the new expression and no definition of the class could be found. Therefore, it can occur during the linking or loading of the unavailable class.

Common causes of the class definition being unavailable at runtime are:

NoClassDefFoundError Example

Here’s an example of a NoClassDefFoundError thrown when a class is attempted to be loaded that is available at compile-time but not at runtime:

class Vehicle < private String make; public String getMake() < return make; > public void setMake(String make) < this.make = make; > > public class NoClassDefFoundErrorExample < public static void main(String args[]) < Vehicle vehicle = new Vehicle(); vehicle.setMake("Audi"); System.out.println("Make = " + vehicle.getMake()); > >

In the above example, an instance of the Vehicle class is created in the NoClassDefFoundErrorExample.main() method and one of its methods is called. When the NoClassDefFoundErrorExample class is compiled and executed using the command line, it works fine and produces the correct output as expected:

$ ls NoClassDefFoundErrorExample.class Vehicle.class NoClassDefFoundErrorExample.java $ javac NoClassDefFoundErrorExample.java $ java NoClassDefFoundErrorExample Make = Audi

Now, if the Vehicle.class file is renamed and the NoClassDefFoundErrorExample class is executed again without recompiling, the NoClassDefFoundError is thrown:

$ mv Vehicle.class Vehicle2.class $ ls NoClassDefFoundErrorExample.class Vehicle2.class NoClassDefFoundErrorExample.java $ java NoClassDefFoundErrorExample Exception in thread "main" java.lang.NoClassDefFoundError: Vehicle at NoClassDefFoundErrorExample.main(NoClassDefFoundErrorExample.java:15) Caused by: java.lang.ClassNotFoundException: Vehicle at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) . 1 more

How to Resolve NoClassDefFoundError

The following steps should be followed to resolve a NoClassDefFoundError in Java:

  • The most common reason for the NoClassDefFoundError is that a particular class is not available in the application classpath. Find out which JAR file contains the problematic class and check whether this JAR is present in the application classpath. If not, the JAR should be added to the classpath and the application should be recompiled and executed again.
  • If that JAR is already present in the classpath, make sure the classpath is not overridden (e.g. by a start-up script). After finding out the exact classpath used by the application, the JAR file should be added to it.
  • Check the manifest file to see if the unavailable class is not defined in the Class-Path attribute. If so, it should be defined.
  • The NoClassDefFoundError can also occur due to the failure of static initialization. Check for the java.lang.ExceptionInInitializerError in the application logs.

Track, Analyze and Manage Errors With Rollbar

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Java errors easier than ever. Sign Up Today!

Источник

Читайте также:  Threading python завершить поток
Оцените статью