Я потратил довольно много времени, чтобы выяснить как исправить ошибку java.lang.NoClassDefFoundError в Java.
В этой инструкции я покажу как исправить эти ошибки, раскрою некоторые секреты NoClassDefFoundError и поделюсь своим опытом в этой области.
NoClassDefFoundError – это самая распространенная ошибка в разработке Java. В любом случае, давайте посмотрим, почему это происходит и что нужно сделать для разрешения проблемы.
NoClassDefFoundError в Java возникает, когда виртуальная машина Java не может найти определенный класс во время выполнения, который был доступен во время компиляции.
Например, если у нас есть вызов метода из класса или доступ к любому статическому члену класса, и этот класс недоступен во время выполнения, JVM сгенерирует NoClassDefFoundError.
Важно понимать, что это отличается от ClassNotFoundException, который появляется при попытке загрузить класс только во время выполнения, а имя было предоставлено во время выполнения, а не во время компиляции. Многие Java-разработчики смешивают эти две ошибки и запутываются.
NoClassDefFoundError возникнет, если класс присутствовал во время компиляции, но не был доступен в java classpath во время выполнения. Обычно появляется такая ошибка:
Exception in thread "main" java.lang.NoClassDefFoundError
Разница между java.lang.NoClassDefFoundError и ClassNotFoundException в Java
[ads-pc-3]
java.lang.ClassNotFoundException и java.lang.NoClassDefFoundError оба связаны с Java Classpath, и они полностью отличаются друг от друга.
ClassNotFoundException возникает, когда JVM пытается загрузить класс во время выполнения, т.е. вы даете имя класса во время выполнения, а затем JVM пытается загрузить его, и если этот класс не найден, он генерирует исключение java.lang.ClassNotFoundException.
Тогда как в случае NoClassDefFoundError проблемный класс присутствовал во время компиляции, и поэтому программа успешно скомпилирована, но не доступна во время выполнения по любой причине.
Приступим к решению ошибки java.lang.NoClassDefFoundError.
Нам нужно добавить NoClassDefFoundError в Classpath или проверить, почему он не доступен в Classpath. Там может быть несколько причин, таких как:
- Класс недоступен в Java Classpath.
- Возможно, вы запускаете вашу программу с помощью jar, а класс не определен в атрибуте ClassPath.
- Любой сценарий запуска переопределяет переменную среды Classpath.
Поскольку NoClassDefFoundError является подклассом java.lang.LinkageError, он также может появиться, если библиотека может быть недоступна. - Проверьте наличие java.lang.ExceptionInInitializerError в файле журнала. NoClassDefFoundError из-за сбоя инициализации встречается довольно часто.
- Если вы работаете в среде J2EE, то видимость Class среди нескольких Classloader также может вызвать java.lang.NoClassDefFoundError.
Примеры
- Простой пример NoClassDefFoundError – класс принадлежит отсутствующему файлу JAR, или JAR не был добавлен в путь к классам, или имя jar было изменено кем-то.
- Класс не находится в Classpath, нет способа узнать это, но вы можете просто посмотреть в System.getproperty (“java.classpath”), и он напечатает classpath оттуда, где можно получить представление о фактическом пути к классам во время выполнения.
- Просто попробуйте запустить явно -classpath с тем классом, который, по вашему мнению, будет работать, и если он работает, это верный признак того – что-то переопределяет java classpath.
NoClassDefFoundError в Java из-за исключения в блоке инициализатора
Это еще одна распространенная причина java.lang.NoClassDefFoundError, когда ваш класс выполняет некоторую инициализацию в статическом блоке и если статический блок генерирует исключение, класс, который ссылается на этот класс, получит NoclassDefFoundError.
Смотрите в журнале java.lang.ExceptionInInitializerError, потому что это может вызвать java.lang.NoClassDefFoundError: Could not initialize class.
Как и в следующем примере кода, во время загрузки и инициализации класса, пользовательский класс генерирует Exception из статического блока инициализатора, который вызывает ExceptionInInitializerError при первой загрузке пользовательского класса в ответ на новый вызов User ().
[ads-pc-3]
/** * Java program to demonstrate how failure of static initialization subsequently cause * java.lang.NoClassDefFoundError in Java. * @author Javin Paul */ public class NoClassDefFoundErrorDueToStaticInitFailure { public static void main(String args[]){ List users = new ArrayList(2); for(int i=0; i<2; i++){ try{ users.add(new User(String.valueOf(i))); }catch(Throwable t){ t.printStackTrace(); } } } } class User{ private static String USER_ID = getUserId(); public User(String id){ this.USER_ID = id; } private static String getUserId() { throw new RuntimeException("UserId Not found"); } } Output java.lang.ExceptionInInitializerError at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23) Caused by: java.lang.RuntimeException: UserId Not found at testing.User.getUserId(NoClassDefFoundErrorDueToStaticInitFailure.java:41) at testing.User.(NoClassDefFoundErrorDueToStaticInitFailure.java:35) ... 1 more java.lang.NoClassDefFoundError: Could not initialize class testing.User at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)
- Поскольку NoClassDefFoundError также является LinkageError, который возникает из-за зависимости от какого-либо другого класса, вы также можете получить java.lang.NoClassDefFoundError, если ваша программа зависит от собственной библиотеки, а соответствующая DLL отсутствует. Помните, что это может также вызвать java.lang.UnsatisfiedLinkError: no dll in java.library.path. Чтобы решить эту проблему, держите dll вместе с JAR.
- Если вы используете файл ANT, создайте JAR, стоит отметить отладку до этого уровня, чтобы убедиться, что скрипт компоновки ANT получает правильное значение classpath и добавляет его в файл manifest.mf.
- Проблема с правами доступа к файлу JAR. Если вы работаете с Java-программой в многопользовательской операционной системе, такой как Linux, вам следует использовать идентификатор пользователя приложения для всех ресурсов приложения, таких как файлы JAR, библиотеки и конфигурации. Если вы используете разделяемую библиотеку, которая используется несколькими приложениями, работающими под разными пользователями, вы можете столкнуться с проблемой прав доступа, например, файл JAR принадлежит другому пользователю и недоступен для вашего приложения.
- Опечатка в конфигурации XML также может вызвать NoClassDefFoundError в Java. Как и большинство Java-фреймворков, таких как Spring, Struts все они используют конфигурацию XML для определения bean-компонентов. В любом случае, если вы неправильно указали имя компонента, он может вызвать ошибку при загрузке другого класса. Это довольно часто встречается в среде Spring MVC и в Apache Struts, где вы получаете множество исключений при развертывании файла WAR или EAR.
- Когда ваш скомпилированный класс, который определен в пакете, не присутствует в том же пакете во время загрузки, как в случае с JApplet.
- Еще одна причина- это нескольких загрузчиков классов в средах J2EE. Поскольку J2EE не использует стандартную структуру загрузчика классов, а зависит от Tomcat, WebLogic, WebSphere и т.д., от того, как они загружают различные компоненты J2EE, такие как WAR-файл или EJB-JAR-файл. Кроме того, если класс присутствует в обоих файлах JAR и вы вызовете метод equals для сравнения этих двух объектов, это приведет к исключению ClassCastException, поскольку объект, загруженный двумя различными загрузчиками классов, не может быть равным.
- Очень редко может происходить Exception in thread “main” java.lang.NoClassDefFoundError: com/sun/tools/javac/Main. Эта ошибка означает, что либо ваш Classpath, PATH или JAVA_HOME не настроен должным образом, либо JDK установка не правильная. Попробуйте переустановить JDK. Замечено, что проблема возникала после установки jdk1.6.0_33 и последующей переустановки JDK1.6.0_25.
I’ve tried both the examples in Oracle’s Java Tutorials. They both compile fine, but at run time, both come up with this error:
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
I think I might have the Main.java
file in the wrong folder.
Here is the directory hierarchy:
graphics
├ Main.java
├ shapes
| ├ Square.java
| ├ Triangle.java
├ linepoint
| ├ Line.java
| ├ Point.java
├ spaceobjects
| ├ Cube.java
| ├ RectPrism.java
And here is 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);
}
}
What am I doing wrong here?
UPDATE
After I put put the Main
class into the graphics
package (I added package graphics;
to it), set the classpath to «_test» (folder containing graphics), compiled it, and ran it using java graphics.Main
(from the command line), it worked.
Really late UPDATE #2
I wasn’t using Eclipse (just Notepad++ and the JDK), and the above update solved my problem. However, it seems that many of these answers are for Eclipse and IntelliJ IDEA, but they have similar concepts.
asked Jul 31, 2013 at 15:00
Jonathan LamJonathan Lam
16.7k17 gold badges67 silver badges94 bronze badges
11
After you compile your code, you end up with .class
files for each class in your program. These binary files are the bytecode that Java interprets to execute your program. The NoClassDefFoundError
indicates that the classloader (in this case java.net.URLClassLoader
), which is responsible for dynamically loading classes, cannot find the .class
file for the class that you’re trying to use.
Your code wouldn’t compile if the required classes weren’t present (unless classes are loaded with reflection), so usually this exception means that your classpath doesn’t include the required classes. Remember that the classloader (specifically java.net.URLClassLoader
) will look for classes in package a.b.c in folder a/b/c/ in each entry in your classpath. NoClassDefFoundError
can also indicate that you’re missing a transitive dependency of a .jar file that you’ve compiled against and you’re trying to use.
For example, if you had a class com.example.Foo
, after compiling you would have a class file Foo.class
. Say for example your working directory is .../project/
. That class file must be placed in .../project/com/example
, and you would set your classpath to .../project/
.
Side note: I would recommend taking advantage of the amazing tooling that exists for Java and JVM languages. Modern IDEs like Eclipse and IntelliJ IDEA and build management tools like Maven or Gradle will help you not have to worry about classpaths (as much) and focus on the code! That said, this link explains how to set the classpath when you execute on the command line.
answered Jul 31, 2013 at 15:05
2
I’d like to correct the perspective of others on NoClassDefFoundError
.
NoClassDefFoundError
can occur for multiple reasons like:
- ClassNotFoundException — .class not found for that referenced class irrespective of whether it is available at compile time or not(i.e base/child class).
- Class file located, but Exception raised while initializing static variables
- Class file located, Exception raised while initializing static blocks
In the original question, it was the first case which can be corrected by setting CLASSPATH to the referenced classes JAR file or to its package folder.
What does it mean by saying «available in compile time»?
- The referenced class is used in the code.
E.g.: Two classes, A and B (extends A). If B is referenced directly in the code, it is available at compile time, i.e.,A a = new B();
What does it mean by saying «not available at compile time»?
- The compile time class and runtime class are different, i.e., for example base class is loaded using classname of child class for example
Class.forName(«classname»)
E.g.: Two classes, A and B (extends A). Code has
A a = Class.forName("B").newInstance();
answered Jan 23, 2014 at 9:09
p1nkrockp1nkrock
1,7861 gold badge10 silver badges6 bronze badges
7
If you got one of these errors while compiling and running:
-
NoClassDefFoundError
-
Error: Could not find or load main class hello
-
Exception in thread «main» java.lang.NoClassDefFoundError:javaTest/test/hello
(wrong name: 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)
————————— Solution ————————
The problem is mostly in packages organization. You should arrange your classes in folders properly regarding to the package classifications in your source code.
On compiling process, use this command:
javac -d . [FileName.java]
To run the class, please use this command:
java [Package].[ClassName]
answered Oct 7, 2014 at 11:23
samisami
3591 gold badge4 silver badges5 bronze badges
2
One possible reason for this NoClassDefFoundError
might be that the class is present in the classpath at Compile time
, but it doesn’t exist in the classpath at Runtime
.
If you’re using Eclipse, make sure you have the shapes
, linepoints
and the spaceobjects
as entries in the .classpath
file.
answered Jul 31, 2013 at 15:02
2
java.lang.NoClassDefFoundError
indicates that something was found at compile time, but not at run time. Maybe you just have to add it to the classpath.
answered Jul 31, 2013 at 15:03
sschrasssschrass
6,9646 gold badges43 silver badges62 bronze badges
1
NoClassDefFoundError in Java:
Definition:
NoClassDefFoundError will come if a class was present during compile time but not available in java classpath during runtime. Normally you will see below line in log when you get NoClassDefFoundError:
Exception in thread «main» java.lang.NoClassDefFoundError
Possible Causes:
-
The class is not available in Java Classpath.
-
You might be running your program using jar command and class was not defined in manifest file’s ClassPath attribute.
-
Any start-up script is overriding Classpath environment variable.
-
Because NoClassDefFoundError is a subclass of java.lang.LinkageError it can also come if one of it dependency like native library may not available.
-
Check for java.lang.ExceptionInInitializerError in your log file. NoClassDefFoundError due to the failure of static initialization is quite common.
-
If you are working in J2EE environment than the visibility of Class among multiple Classloader can also cause java.lang.NoClassDefFoundError, see examples and scenario section for detailed discussion.
Possible Resolutions:
-
Verify that all required Java classes are included in the application’s classpath. The most common mistake is not to include all the necessary classes, before starting to execute a Java application that has dependencies on some external libraries.
-
The classpath of the application is correct, but the Classpath environment variable is overridden before the application’s execution.
-
Verify that the aforementioned ExceptionInInitializerError does not appear in the stack trace of your application.
Resources:
3 ways to solve java.lang.NoClassDefFoundError in Java J2EE
java.lang.NoClassDefFoundError – How to solve No Class Def Found Error
answered Aug 8, 2016 at 8:19
AftabAftab
2,85330 silver badges40 bronze badges
The no class definition exception occurs when the intended class is not found in the class path.
At compile time class: Class was generated from the Java compiler, but somehow at run time the dependent class is not found.
Let’s go through one simple example:
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";
}
}
Now let’s assume that the above two Java source code are placed in some folder, let’s say «NoClassDefinationFoundExceptionDemo»
Now open a shell (assuming Java is already being set up correctly)
-
Go to folder «NoClassDefinationFoundExceptionDemo»
-
Compile Java source files
javac ClassB
javac ClassA -
Both files are compiled successfully and generated class files in the same folder as ClassA.class and ClassB.class
-
Now since we are overriding ClassPath to the current working director, we execute the following command
java -cp . ClassA
and it worked successfully and you will see the output on the screen -
Now let’s say, you removed ClassB.class file from the present directory.
And now you execute the command again.
java -cp . ClassA Now it will greet you with NoClassDefFoundException. As ClassB which is a dependency for ClassA is not found in the classpath (i.e., the present working directory).
answered Mar 22, 2015 at 16:28
bharatjbharatj
2,2771 gold badge24 silver badges25 bronze badges
If your project is in a package like com.blahcode
and your class is called Main
, the compiled files may be output in a directory structure like ./out/com/blahcode/Main.class
. This is especially true for IntelliJ IDEA.
When trying to run from a shell or cmd, you need to cd
to that which contains com
as a sub-directory.
cd out
java -classpath . com.blahcode.Main
answered Sep 27, 2014 at 23:32
HypershadsyHypershadsy
3884 silver badges13 bronze badges
If you are «starting» a class from a JAR file, make sure to start with the JAR full path. For example, (if your «main class» is not specified in Manifest):
java -classpath "./dialer.jar" com.company.dialer.DialerServer
And if there are any dependencies, such dependencies to other JAR files, you can solve such a dependency
- either by adding such JAR files (full path to each JAR file) to the class path. For example,
java -classpath "./libs/phone.jar;./libs/anotherlib.jar;./dialer.jar" com.company.dialer.DialerServer
- or by editing the JAR manifest by adding «dependency JAR filess» to the manifest. Such a manifest file might look like:
Manifest-Version: 1.0
Class-Path: phone.jar anotherlib.jar
Build-Jdk-Spec: 1.8
Main-Class: com.company.dialer.DialerServer
- or (if you are a developer having source code) you can use Maven to prepare a manifest for you by adding to the *.pom file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.company.dialer.DialerServer</mainClass>
<!-- Workaround for Maven bug #MJAR-156 (https://jira.codehaus.org/browse/MJAR-156) -->
<useUniqueVersions>false</useUniqueVersions>
</manifest>
</archive>
</configuration>
</plugin>
Please note that the above example uses ;
as a delimiter in classpath (it is valid for the Windows platform). On Linux, replace ;
by :
.
For example,
java -classpath ./libs/phone.jar:./libs/anotherlib.jar:./dialer.jar
com.company.dialer.DialerServer
answered May 28, 2021 at 8:21
walter33walter33
7265 silver badges11 bronze badges
I have faced with the problem today. I have an Android project and after enabling multidex
the project wouldn’t start anymore.
The reason was that I had forgotten to call the specific multidex method that should be added to the Application class
and invoked before everything else.
MultiDex.install(this);
Follow this tutorial to enable multidex correctly. https://developer.android.com/studio/build/multidex.html
You should add these lines to your Application class
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
answered Nov 24, 2017 at 14:50
CROSPCROSP
4,4794 gold badges38 silver badges89 bronze badges
After working on a NetBeans project for many months, I suddenly got the NoClassDefFoundError message shortly after getting a «Low Memory» alert. Doing a Clean rebuild didn’t help, but closing NetBeans altogether and reopening the project there were no error reports.
answered Apr 14, 2016 at 13:51
Ed SEd S
2395 silver badges20 bronze badges
This answer is specific to a java.lang.NoClassDefFoundError happening in a service:
My team recently saw this error after upgrading an rpm that supplied a service. The rpm and the software inside of it had been built with Maven, so it seemed that we had a compile time dependency that had just not gotten included in the rpm.
However, when investigating, the class that was not found was in the same module as several of the classes in the stack trace. Furthermore, this was not a module that had only been recently added to the build. These facts indicated it might not be a Maven dependency issue.
The eventual solution: Restart the service!
It appears that the rpm upgrade invalidated the service’s file handle on the underlying JAR file. The service then saw a class that had not been loaded into memory, searched for it among its list of jar file handles, and failed to find it because the file handle that it could load the class from had been invalidated. Restarting the service forced it to reload all of its file handles, which then allowed it to load that class that had not been found in memory right after the rpm upgrade.
answered Dec 2, 2016 at 16:33
2
For my project, what solved the issue was that Chrome browser and chromedriver were not compatibles. I had a very old version of the driver that could not even open the browser. I just downloaded the latest version of both and problem solved.
How did I discover the issue? Because I ran my project using the Selenium native Firefox driver with an old version of FF included with my application. I realized the problem was incompatibility between browser and driver.
Hope this can help anyone with a similar issue as mine, that generated this same Error Message.
answered Jan 4, 2019 at 19:37
Kyon PerezKyon Perez
1241 silver badge13 bronze badges
I’m developing an Eclipse based application also known as RCP (Rich Client Platform).
And I have been facing this problem after refactoring (moving one class from an plugIn to a new one).
Cleaning the project and Maven update didn’t help.
The problem was caused by the Bundle-Activator which haven’t been updated automatically. Manual update of the Bundle-Activator under MANIFEST.MF in the new PlugIn has fixed my problem.
answered Apr 6, 2018 at 8:41
If you are using more than one module, you should have
dexOptions {
preDexLibraries = false
}
in your build file.
Pang
9,491146 gold badges81 silver badges122 bronze badges
answered Apr 20, 2017 at 8:47
I had the same issue with my Android development using Android studio. Solutions provided are general and did not help me (at least for me).
After hours of research, I found the following solution and it may help to Android developers who are doing development using Android Studio.
Modify the setting as below:
Preferences → Build, Execution, Deployment → Instant Run → *uncheck the first option.
With this change I am up and running.
answered Apr 28, 2016 at 17:29
maskmask
6,1423 gold badges24 silver badges23 bronze badges
My two cents in this chain:
Ensure that the classpath contains full paths (/home/user/lib/some_lib.jar
instead of ~/lib/some_lib.jar
) otherwise you can still face NoClassDefFoundError
error.
answered Jun 17, 2015 at 15:02
khkarenskhkarens
1,3051 gold badge11 silver badges15 bronze badges
1
Don’t use test classes outside the module
I do not have a solution, just another flavour of the «present at compilation, absent at run time» case.
I was trying to use a very convenient method from a JUnit test class from another test class which resides in a different module. That’s a no-no, since test code is not part of the packaged jar, but I didn’t realize because it appears visible for the user class from within Eclipse.
My solution was to place the method in a existing utilities class that is part of the production code.
answered Dec 5, 2019 at 16:01
manuelvigarciamanuelvigarcia
1,5661 gold badge20 silver badges32 bronze badges
I get NoClassFoundError when classes loaded by the runtime class loader cannot access classes already loaded by the Java rootloader. Because the different class loaders are in different security domains (according to Java) the JVM won’t allow classes already loaded by the rootloader to be resolved in the runtime loader address space.
Run your program with ‘java -javaagent:tracer.jar [YOUR ‘java’ ARGUMENTS]’
It produces output showing the loaded class, and the loader environment that loaded the class. It’s very helpful tracing why a class cannot be resolved.
// 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;
}
});
}
}
answered Sep 9, 2015 at 11:56
codeDrcodeDr
1,52517 silver badges20 bronze badges
It happened to me in Android Studio.
The solution that worked for me: just restart Android Studio.
answered Apr 13, 2016 at 11:21
yanishyanish
2572 silver badges15 bronze badges
Check that if you have a static handler in your class. If so, please be careful, cause static handler only could be initiated in thread which has a looper, the crash could be triggered in this way:
-
Firstly, create the instance of class in a simple thread and catch the crash.
-
Then call the field method of Class in main thread, you will get the NoClassDefFoundError.
Here is the test code:
public class MyClass{
private static Handler mHandler = new Handler();
public static int num = 0;
}
In your onCreate method of the Main activity, add the test code part:
@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
}
There is a simple way to fix it using a handlerThread to the init handler:
private static Handler mHandler;
private static HandlerThread handlerThread = new HandlerThread("newthread");
static {
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper(), mHandlerCB);
}
answered Jan 16, 2017 at 3:51
MichaelMichael
6466 silver badges16 bronze badges
0
One source of error for this exception could stem from inconsistent definitions for Proguard, e.g. a missing
-libraryJars «path.to.a.missing.jar.library».
This explains why compilation and running works fine, given that the JAR file is there, while clean and build fails. Remember to define the newly added JAR libraries in the ProGuard setup!
Note that error messages from ProGuard are really not up to standard, as they are easily confused with similar Ant messages arriving when the JAR file is not there at all. Only at the very bottom will there be a small hint of ProGuard in trouble. Hence, it is quite logical to start searching for traditional classpath errors, etc., but this will be in vain.
Evidently, the NoClassDefFound exception will be the results when running, e.g., the resulting executable JAR file built and based on a lack of ProGuard consistency. Some call it ProGuard «Hell».
answered Nov 2, 2017 at 20:04
carlcarl
5033 silver badges10 bronze badges
I use the FileSync plugin for Eclipse, so I can live debug on Tomcat. I received NoClassFoundError
, because I had added a sync entry for the bin
directory in the Eclipse workspace => classes
in the metadata
for Tomcat, but I hadn’t also added a folder sync for the extlib
directory in Eclipse =>
C:UsersStuarteclipse-workspace.metadata.pluginsorg.eclipse.wst.server.coretmp0webappsmyAppWEB-INFlib
answered Dec 6, 2017 at 10:56
If you recently added multidex support in Android Studio like this:
// To support MultiDex
implementation 'com.android.support:multidex:1.0.1'
So your solution is just extend from MultiDexApplication instead of Application:
public class MyApp extends MultiDexApplication {
answered Apr 30, 2018 at 6:36
Hamid ZandiHamid Zandi
2,68624 silver badges32 bronze badges
In my environment, I encountered this issue in a unit test. After appending one library dependency to *.pom, that’s fixed.
Example:
Error message:
java.lang.NoClassDefFoundError: com/abc/def/foo/xyz/Iottt
POM content:
<dependency>
<groupId>com.abc.def</groupId>
<artifactId>foo</artifactId>
<scope>test</scope>
</dependency>
answered Apr 8, 2020 at 6:59
Mystic LinMystic Lin
3654 silver badges15 bronze badges
I got this error after a Git branch change. For the specific case of Eclipse, there were missed lines in the .settings directory for the org.eclipse.wst.common.component file. As you can see below.
Restoring the project dependencies with Maven install would help.
answered May 20, 2020 at 1:54
LeonardoLeonardo
1,4412 gold badges9 silver badges6 bronze badges
If you are using gradlew
, go to ./gradle/wrapper/gradle-wrapper.properties
and change distributionUrl
to the correct version of Gradle.
If you are using JDK14, try:
distributionUrl=https://services.gradle.org/distributions/gradle-6.3-bin.zip
answered Jun 28, 2020 at 12:25
ehacinomehacinom
7,9007 gold badges40 silver badges64 bronze badges
For Meteor or Cordova users,
It can be caused by the Java version you use. For Meteor and Cordova, stick with version 8 for now.
-
Check available Java versions
/usr/libexec/java_home -V
and look for the path name for Java version 8 -
Set the path for Java version 8
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home
-
Check if it is done
echo $JAVA_HOME
Go on and continue coding.
answered Jan 18, 2021 at 7:50
mcnkmcnk
1,5993 gold badges18 silver badges29 bronze badges
The Java 11 + Eclipse solution:
This solution is for you if you are not using module-info.java
in your Eclipse project, and you added the JAR files manually instead of using Maven/Gradle.
- Right click project → Build path → Configure build path → libraries tab
- Remove the problematic JAR file from the modulepath
- Add the JAR file to the classpath
More information is in
In Eclipse, what is the difference between modulepath and classpath?.
answered Apr 22, 2021 at 22:02
Mister SmithMister Smith
27.2k20 gold badges108 silver badges192 bronze badges
I deleted the folder «buid» and «out», and the IDE rebuild again this folders with updated content files.
answered Apr 7, 2022 at 13:25
I know how frustrating is to see Exception in thread «main» java.lang.NoClassDefFoundError, which is a manifestation of NoClassDefFoundError in Java. I have seen it a couple of times and spent quite a lot of time initially to figure out what is wrong, which class is missing etc. The first mistake I did was mingling java.lang.ClassNotfoundException and NoClassDefFoundError, in reality, are totally different, and my second mistake was using the trial and error method to solve this java.lang.NoClassDefFoundError instead of understanding why NoClassDefFoundError is coming, what is the real reason behind NoClassDefFoundError and how to resolve this.
In this Java tutorial, I have tried to rectify that mistakes and uncover some secrets of NoClassDefFoundError in Java and will share my experience around it. NoClassDefFoundError is not something that cannot be resolved or is hard to resolve it’s just its manifestation that puzzles most Java developers.
This is the most common error in Java development along with java.lang.OutOfMemoroyError: Java heap space and java.lang.OutOfMemoryError: PermGen space Anyway lets see Why NoClassDefFoundError comes in Java and what to do to resolve NoClassDefFoundError in Java.
What is the reason for NoClassDefFoundError in Java?
NoClassDefFoundError in Java comes when Java Virtual Machine is not able to find a particular class at runtime which was available at compile time. For example, if we have a method call from a class or accessing any static member of a class and that class is not available during run-time then JVM will throw NoClassDefFoundError.
It’s important to understand that this is different than ClassNotFoundException which comes while trying to load a class at run-time only and the name was provided during runtime, not at compile-time. Many Java developer mingles this two Error and gets confused.
In short, NoClassDefFoundError will come if a class was present during compile time but not available in java classpath during runtime. Normally you will see the below line in the log when you get NoClassDefFoundError:
Exception in thread «main» java.lang.NoClassDefFoundError
Exception in thread “main” simply indicates that it’s the “main” thread that is not able to find a particular class it could be any thread so just don’t worry. The difference between this error coming in the main thread and another thread is when Exception in thread “main” comes program crashes or shut itself down as opposed to other thread in which case your program will continue to run.
If you are really curious and think that you understand how class loading works, I suggest you try some puzzles from Joshua Bloch’s Java Puzzlers, it has got some really tricky questions to test your knowledge.
The difference between java.lang.NoClassDefFoundError and ClassNotFoundException in Java
Many times we confused ourselves with java.lang.ClassNotFoundException and java.lang.NoClassDefFoundError, though both of them are related to Java Classpath they are completely different from each other.
ClassNotFoundException comes when JVM tries to load a class at runtime dynamically means you give the name of the class at runtime and then JVM tries to load it and if that class is not found in the classpath it throws java.lang.ClassNotFoundException.
While in the case of NoClassDefFoundError the problematic class was present during Compile time and that’s why the program successfully compiled but was not available during runtime for any reason.
NoClassDefFoundError is easier to solve than ClassNotFoundException in my opinion because here we know that Class was present at build time, but it totally depends upon the environment if you are working in the J2EE environment then you can get NoClassDefFoundError even if the class is present because it may not be visible to the corresponding class loader. See my post NoClassDefFoundError vs ClassNotFoundException in Java for more details.
How to resolve java.lang.NoClassDefFoundError in Java
The obvious reason for NoClassDefFoundError is that a particular class is not available in Classpath, so we need to add that into Classpath or we need to check why it’s not available in Classpath if we are expecting it to be. There could be multiple reasons like:
2) You might be running your program using the jar command and class was not defined in the manifest file’s ClassPath attribute.
3) Any start-up script is an overriding Classpath environment variable.
4) Because NoClassDefFoundError is a subclass of java.lang.LinkageError it can also come if one of it dependency like native library may not available.
4) Check for java.lang.ExceptionInInitializerError in your log file. NoClassDefFoundError due to the failure of static initialization is quite common.
5) If you are working in J2EE environment than the visibility of Class among multiple Classloader can also cause java.lang.NoClassDefFoundError, see examples and scenario section for detailed discussion.
We will now see a couple of examples and scenarios when java.lang.NoClassDefFoundError has come before and how it’s been resolved. This can help you to troubleshoot the root cause of NoClassDefFoundError in Java application.
NoClassDefFoundError in Java — Example and Scenarios
1. A simple example of NoClassDefFoundError is class belongs to a missing JAR file or JAR was not added into classpath or sometimes jar’s name has been changed by someone like in my case one of my colleagues has changed tibco.jar into tibco_v3.jar and the program is failing with java.lang.NoClassDefFoundError and I were wondering what’s wrong.
2. The class is not in Classpath, there is no sure-shot way of knowing it but many times you can just have a look to print System.getproperty(«java.classpath») and it will print the classpath from there you can at least get an idea of your actual runtime classpath.
3. Just try to run with explicitly -classpath option with the classpath you think will work and if it’s working then it’s a sure shot sign that someone is overriding java classpath.
NoClassDefFoundError in Java due to Exception in Static Initializer block
This is another common reason for java.lang.NoClassDefFoundError, when your class performs some static initialization in a static block like many Singleton classes initialized itself on the static block to take advantage of thread-safety provided by JVM during the class initialization process, and if static block throws an Exception, the class which is referring to this class will get NoclassDefFoundError in Java.
If you look at your log file you should watch for any java.lang.ExceptionInInitializerError because that could trigger java.lang.NoClassDefFoundError: Could not initialize class on other places.
Like in the below code example, During class loading and initialization User class are throwing Exception from the static initializer block, which triggers ExceptionInInitializerError during the first time loading of User class in response to new User() call.
Later rest of new User() are failing as java.lang.NoClassDefFoundError. the situation gets worst if original ExceptionInInitializerError, which is root cause here is silently eaten by any code.
Code Example of NoClassDefFoundError due to Static block Exception:
/**
* Java program to demonstrate how failure of static initialization subsequently cause
* java.lang.NoClassDefFoundError in Java.
* @author Javin Paul
*/
public class NoClassDefFoundErrorDueToStaticInitFailure {public static void main(String args[]){
List
<User> users = new ArrayList<User>(2);for(int i=0; i<2; i++){
try{
users.add(new User(String.valueOf(i))); //will throw NoClassDefFoundError
}catch(Throwable t){
t.printStackTrace();
}
}
}
}class User{
private static String USER_ID = getUserId();public User(String id){
this.USER_ID = id;
}
private static String getUserId() {
throw new RuntimeException(«UserId Not found»);
}
}
Output
java.lang.ExceptionInInitializerError
at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)
Caused by: java.lang.RuntimeException: UserId Not found
at testing.User.getUserId(NoClassDefFoundErrorDueToStaticInitFailure.java:41)
at testing.User.<clinit>(NoClassDefFoundErrorDueToStaticInitFailure.java:35)
… 1 more
java.lang.NoClassDefFoundError: Could not initialize class testing.User
at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)
5) Since NoClassDefFoundError is an also a LinkageError that arises due to dependency on some other class, you can also get java.lang.NoClassDefFoundError if your program is dependent on the native library and the corresponding DLL is not there. Remember this can also trigger java.lang.UnsatisfiedLinkError: no dll in java.library.path Exception Java. In order to solve this keep your dll along with JAR.
6) If you are using the ANT build file create JAR and manifest file then its worth noting to debug till that level to ensure that ANT build script is getting the correct value of classpath and appending it to manifest.mf file.
7) Permission issue on the JAR file can also cause NoClassDefFoundError in Java. If you are running your Java program in a multi-user operating system like Linux then you should be using the application user id for all your application resources like JAR files, libraries, and configuration.
If you are using a shared library which is shared among multiple application which runs under different users then you may run into permission issue, like JAR file is owned by some other user and not accessible to your application.
One of our readers “it’s me said”, faced java.lang.NoClassDefFoundError due to this reason. See his comment also.
Typo on XML Configuration can also cause NoClassDefFoundError in Java. As most of Java frameworks like Spring, Struts they all use XML configuration for specifying beans. By any chance, if you put the bean name wrong, it may surface as java.lang.NoClassDefFoundError while loading other class which has a dependency on the wrongly named bean.
This is quite common in the Spring MVC framework and Apache Struts where you get tons of Exception in thread «main» java.lang.NoClassDefFoundError, while deploying your WAR or EAR file.
9) Another example of java.lang.NoClassDefFoundError, as mentioned by our reader Nick, is that when your compiled class which is defined in a package, doesn’t present in the same package while loading like in the case of JApplet it will throw NoClassDefFoundError in Java. Also, see Nick’s comment on this error.
10) java.lang.NoClassDefFoundError can be caused due to multiple classloaders in J2EE environments. Since J2EE doesn’t mention standard classloader structure and it depends on different vendors like Tomcat, WebLogic, WebSphere on how they load different components of J2EE like WAR file or EJB-JAR file.
In order to troubleshoot NoClassDefFoundError in the J2EE application knowledge of How ClassLoader works in Java is mandatory. Just to recap ClasLoader works on three principles delegation, visibility, and uniqueness.
Delegation means every request to load a class is delegated to the parent classloader, visibility means an ability to found classes loaded by the classloader, all child classloaders can see classes loaded by parent classloader, but parent classloader can not see the class loaded by child classloaders.
Uniqueness enforces that class loaded by the parent will never be reloaded by child classloaders. Now suppose if a class says User is present in both WAR file and EJB-JAR file and loaded by WAR classloader which is child classloader which loads the class from EJB-JAR. When a code in EJB-JAR refers to this User class, Classloader which loaded all EJB class doesn’t found that because it was loaded by WAR classloader which is a child of it.
This will result in java.lang.NoClassDefFoundError for User class. Also, If the class is present in both JAR file and you will call equals method to compare those two objects, it will result in ClassCastException as the object loaded by two different classloaders can not be equal.
11) Some of the readers of this blog also suggested that they get Exceptions in thread «main» java.lang.NoClassDefFoundError: com/sun/tools/javac/Main , this error means either your Classpath, PATH or JAVA_HOME is not setup properly or JDK installation is not correct. which can be resolved by reinstalling JDK?
If you are getting this error try to reinstall JDK. One of our readers got this issue after installing jdk1.6.0_33 and then reinstalling JDK1.6.0_25, he also has his JRE and JDK in a different folder. See his comment also by searching JDK1.6.0_33.
12) Java program can also throw java.lang.NoClassDefFoundError during linking which occurs during class loading in Java. One of the examples of this scenario is just deleted the User class from our static initializer failure example after compilation and they try to run the program.
This time, you will get java.lang.NoClassDefFoundError directly without java.lang.ExceptionInInitializerError and message for NoClassDefFoundError are also just printing the name of the class as testing/User i.e. User class from the testing package. Watch out for this carefully as here root cause is absent of User.class file.
java.lang.NoClassDefFoundError: testing/User
at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)
Let me know how exactly you are facing NoClassDefFoundError in Java and I will guide you on how to troubleshoot it if you are facing something new way than I listed above we will probably document it for the benefit of others and again don’t be afraid with Exception in thread «main» java.lang.NoClassDefFoundError.
Other Exception and Error handling Tutorials from Javareivisted
- How to solve UnSupportedClassVersionError in Java
- Java.net.BindException: Address already in use: JVM_Bind:8080 Solution
- JDBC — java.lang.ClassNotFoundException: com.mysql.jdbc.Driver Solution
- How to Fix java.lang.classnotfoundexception oracle.jdbc.driver.oracledriver
- How to solve java.lang.ClassNotFoundException: org.Springframework.Web.Context.ContextLoaderListener
- How to fix java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
- How to solve java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
Перевод: Саянкин А.А.
Содержание
- 1 Введение
- 2 В чём причина NoClassDefFoundError в Java?
- 3 Разница между java.lang.NoClassDefFoundError и ClassNotFoundException в Java
- 4 NoClassDefFoundError в Java. Примеры и сценарии
- 5 Загрузчик классов в Java
- 6 NoClassDefFoundError в Java из-за исключения в статическом инициализирующем блоке
- 7 Перечень использованных ссылок
Предисловие переводчика
Данная статья представляет перевод оригинальных публикаций следующих авторов:
- Джэйвин Пол (Javin Paul) Difference between ClassNotFoundException vs NoClassDefFoundError in Java, 3 ways to solve java.lang.NoClassDefFoundError in Java J2EE;
- Пьер Хьюго Шарбоне (Pierre Hugues Charbonneau) java.lang.NoClassDefFoundError: How to resolve – Part 1;
- coobird What is the difference between NoClassDefFoundError and ClassNotFoundException?
Переводчик выражает благодарность Виктору Жуковскому за ценные правки и обсуждение рукописи.
Введение
Известно насколько неприятно видеть исключение java.lang.NoClassDefFoundError в потоке «main«. Многие разработчики проводят много времени прежде всего пытаясь понять, что пошло не так, какого класса не хватает и в чём суть проблемы. Во-первых, они путают между собой ClassNotfoundException и NoClassDefFoundError, хотя на самом деле это два совершенно разных исключения. Во-вторых, они используют метод «научного тыка» для решения проблемы NoClassDefFoundError вместо ясного понимания почему ошибка случилась и как её исправить. В этой статье по Java мы откроем некоторые секреты исправления ошибки NoClassDefFoundError в Java и поделимся своим опытом решения подобной проблемы.
Ошибка NoClassDefFoundError не является чем-то, что не может быть устранено или чем-то, что очень трудно устраняемо — нет, NoClassDefFoundError всего лишь проявление другой, более глубинной ошибки, что сбивает с толку большинство Java разработчиков. NoClassDefFoundError наиболее распространённая ошибка в Java разработке наряду с java.lang.OutOfMemoroyError: Java heap space и java.lang.OutOfMemoryError: PermGen space. Давайте посмотрим почему в Java происходит NoClassDefFoundError и что делать, чтобы её исправить.
В чём причина NoClassDefFoundError в Java?
NoClassDefFoundError в Java происходит тогда, когда виртуальная машина Java во время исполнения кода не может найти определённый класс, который был доступен во время компиляции. Например, если мы вызываем метод из класса или обращаемся к статическому члену класса и этот класс не доступен во время выполнения, то виртуальная машина Java выбрасывает NoClassDefFoundError. Важно понимать, что эта ошибка отличается от исключения ClassNotFoundException, которое происходит при попытке загрузки класса во время выполнения, причём важно, что имя этого класса было определено только во время выполнения, но не во время компиляции кода. Многие Java разработчики путают эти две ошибки и приходят в тупик при попытке разрешить вопрос.
Коротко говоря, NoClassDefFoundError происходит, если класс присутствовал во время компиляции, но не доступен в classpath во время исполнения. Обычно в этом случае вы увидите следующую строку в журнале ошибок:
Exception in thread «main» java.lang.NoClassDefFoundError
Фраза Exception in thread «main» означает, что именно поток «main» не может найти определённый класс. Вместо «main» может быть любой поток. Разница между тем, когда эта ошибка возникает в потоке «main» и в другом потоке в состоит том, что при возникновении в потоке «main» программа останавливается, а при возникновении в ином потоке, напротив, продолжает выполнение после ошибки.
Разница между java.lang.NoClassDefFoundError и ClassNotFoundException в Java
Прежде чем рассмотреть разницу между ClassNotFoundException и NoClassDefFoundError давайте рассмотрим, что между ними общего и что приводит к путанице между этими двумя ошибками:
- Обе ошибки связаны с недоступностью класса во время выполнения;
- Обе ошибки связаны с Java Classpath .
Теперь о различиях.
- ClassNotFoundException возникает в Java, если мы пытаемся загрузить класс во время выполнения используя методы Class.forName(), ClassLoader.loadClass() или ClassLoader.findSystemClass() , причём необходимый класс не доступен для Java. Зачастую причина тому — неправильный Classpath. В большинстве своём нам кажется, что мы используем корректный Classpath, но оказывается, что приложение использует совсем другой Classpath — не тот, который мы ожидали. Например, Classpath , заданный в манифесте jar файла, перезаписывает Classpath в переменной окружения CLASSPATH или опции -cp , заданной при запуске jar файла. В отличие от ClassNotFoundException в случае с NoClassDefFoundError проблемный класс присутствовал во время компиляции, и, поэтому, программа успешно прошла компиляцию, но по некоторой причине класс отсутствует во время исполнения. На мой взгляд решить NoClassDefFoundError легче чем ClassNotFoundException, поскольку вы точно знаете, что класс присутствовал во время сборки, но, в общем случае, это сильно зависит от среды разработки. Если вы работаете с J2EE окружением, вы можете получить NoClassDefFoundError даже если класс присутствует, поскольку он может быть невидимым для соответствующего загрузчика классов.
- ClassNotFoundException представляет собой проверяемое исключение, унаследованное непосредственно от класса java.lang.Exception, требующее явной обработки, в то время как NoClassDefFoundError это java.lang.Error, унаследованный от java.lang.LinkageError.
- ClassNotFoundException возникает в результате явной загрузки класса методами Class.forName(), ClassLoader.loadClass() или ClassLoader.findSystemClass(), в то время как NoClassDefFoundError — результат неявной загрузки класса, происходящей при попытке вызова метода из другого класса или доступа к его свойству.
NoClassDefFoundError в Java. Примеры и сценарии
Итак, очевидная причина NoClassDefFoundError состоит в том, что определённый класс не доступен в Classpath, так что нам нужно добавить его в Classpath или понять почему его нет в Classpath, хотя мы ожидаем его там найти. Для этого могут быть несколько причин:
- Класс не задан непосредственно в самой переменной Classpath.
- Распечатайте значение System.getproperty(«java.classpath») в Java программе.
- Проверьте, не перезаписывает ли значение переменной окружения Classpath скрипт, запускающий приложение. Запустите программу с явной опцией -classpath, где укажите тот classpath, который по вашему мнению сработает, и если в этом случае программа заработает, то это хороший знак, что кто-то перезатирает ваш classpath.
- Класс отсутствует по местоположению, указанному в переменной Classpath.
- Проверьте, не удалил ли кто-то ваш jar-файл, или быть может переименовал его.
- Загрузчик классов не имеет прав на чтение файла, указанного в переменной Classpath, на уровне операционной системы.
- Используйте один и тот же id пользователя для всех ресурсов вашего приложения: JAR файлов, библиотек и файлов конфигурации.
- Класс не определён в атрибуте ClassPath файла манифеста, при запуске программы с помощью команды jar.
- Если вы используете файл сборки ANT для создания JAR архива и файла манифеста, то проверьте получает ли скрипт сборки ANT правильное значение classpath и добавляет ли его в файл manifest.mf.
- Виртуальная машина Java не нашла одну из зависимостей, например, нативную библиотеку. Эта ошибка выбрасывается поскольку NoClassDefFoundError является наследником java.lang.LinkageError.
- Храните ваши dll совместно с jar-файлами.
- Виртуальная машина Java не смогла завершить статическую инициализацию класса.
- Проверьте наличие ошибки java.lang.ExceptionInInitializerError в вашем журнале ошибок.
- Родительский загрузчик классов не видит класс, поскольку тот был уже загружен дочерним загрузчиком. Если вы работаете со средой J2EE, то неверная настройка видимости класса среди загрузчиков классов может также привести к java.lang.NoClassDefFoundError.
- Опечатка в XML конфигурации также может привести к NoClassDefFoundError в Java. Большинство программных платформ вроде Spring и Struts используют XML конфигурации для определения бинов. Случайно перепутав имя бина, вы можете получить java.lang.NoClassDefFoundError при загрузке другого класса, который зависит от бина. Это случается довольно часто в программных платформах Spring MVC и Apache Struts, где вы получаете тонны ошибок Exception in thread «main» java.lang.NoClassDefFoundError во время установки WAR или EAR файла.
- Переменные окружения или JDK установлены неверно.
- Проверьте переменные PATH и JAVA_HOME.
- Поставьте JDK другой версии.
Загрузчик классов в Java
Вкратце напомним, что загрузчик классов использует три основных принципа в своей работе: делегирование, видимость и уникальность.
- Делегирование означает, что каждый запрос на загрузку класса делегируется родительскому загрузчику классов.
- Видимость означает возможность найти классы загруженные загрузчиком классов: все дочерние загрузчики классов могут видеть классы, загруженные родительским загрузчиком, но родительский загрузчик не может видеть класс, загруженный дочерним.
- Уникальность гарантирует, что класс, загруженный родительским загрузчиком, не загружается повторно дочерним загрузчиком.
Каждый экземпляр загрузчика классов имеет связанный с ним родительский загрузчик классов. Предположим, загрузчик классов вашего приложения должен загрузить класс A. Первым делом загрузчик классов вашего приложения попытается делегировать поиск класса A своему родительскому загрузчику, прежде чем сам попытается его загрузить. Вы можете пройтись по длинной цепочке родительских загрузчиков пока не дойдёте до стартового загрузчика виртуальной машины Java.
Так в чём же тут проблема? Если класс A найден и загружен каким-нибудь родительским загрузчиком, это значит, что дочерний загрузчик загружать его уже не будет, а вы, возможно, именно этого и ждёте, что и приводит к NoClassDefFoundError.
Для лучшего понимания изобразим весь процесс загрузки в контексте платформы Java EE.
NoClassDefFoundError in Java — Example and Scenarios
1. A simple example of NoClassDefFoundError is class belongs to a missing JAR file or JAR was not added into classpath or sometimes jar’s name has been changed by someone like in my case one of my colleagues has changed tibco.jar into tibco_v3.jar and the program is failing with java.lang.NoClassDefFoundError and I were wondering what’s wrong.
2. The class is not in Classpath, there is no sure-shot way of knowing it but many times you can just have a look to print System.getproperty(«java.classpath») and it will print the classpath from there you can at least get an idea of your actual runtime classpath.
3. Just try to run with explicitly -classpath option with the classpath you think will work and if it’s working then it’s a sure shot sign that someone is overriding java classpath.
NoClassDefFoundError in Java due to Exception in Static Initializer block
This is another common reason for java.lang.NoClassDefFoundError, when your class performs some static initialization in a static block like many Singleton classes initialized itself on the static block to take advantage of thread-safety provided by JVM during the class initialization process, and if static block throws an Exception, the class which is referring to this class will get NoclassDefFoundError in Java.
If you look at your log file you should watch for any java.lang.ExceptionInInitializerError because that could trigger java.lang.NoClassDefFoundError: Could not initialize class on other places.
Like in the below code example, During class loading and initialization User class are throwing Exception from the static initializer block, which triggers ExceptionInInitializerError during the first time loading of User class in response to new User() call.
Later rest of new User() are failing as java.lang.NoClassDefFoundError. the situation gets worst if original ExceptionInInitializerError, which is root cause here is silently eaten by any code.
Code Example of NoClassDefFoundError due to Static block Exception:
/**
* Java program to demonstrate how failure of static initialization subsequently cause
* java.lang.NoClassDefFoundError in Java.
* @author Javin Paul
*/
public class NoClassDefFoundErrorDueToStaticInitFailure {public static void main(String args[]){
List
<User> users = new ArrayList<User>(2);for(int i=0; i<2; i++){
try{
users.add(new User(String.valueOf(i))); //will throw NoClassDefFoundError
}catch(Throwable t){
t.printStackTrace();
}
}
}
}class User{
private static String USER_ID = getUserId();public User(String id){
this.USER_ID = id;
}
private static String getUserId() {
throw new RuntimeException(«UserId Not found»);
}
}
Output
java.lang.ExceptionInInitializerError
at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)
Caused by: java.lang.RuntimeException: UserId Not found
at testing.User.getUserId(NoClassDefFoundErrorDueToStaticInitFailure.java:41)
at testing.User.<clinit>(NoClassDefFoundErrorDueToStaticInitFailure.java:35)
… 1 more
java.lang.NoClassDefFoundError: Could not initialize class testing.User
at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)
5) Since NoClassDefFoundError is an also a LinkageError that arises due to dependency on some other class, you can also get java.lang.NoClassDefFoundError if your program is dependent on the native library and the corresponding DLL is not there. Remember this can also trigger java.lang.UnsatisfiedLinkError: no dll in java.library.path Exception Java. In order to solve this keep your dll along with JAR.
6) If you are using the ANT build file create JAR and manifest file then its worth noting to debug till that level to ensure that ANT build script is getting the correct value of classpath and appending it to manifest.mf file.
7) Permission issue on the JAR file can also cause NoClassDefFoundError in Java. If you are running your Java program in a multi-user operating system like Linux then you should be using the application user id for all your application resources like JAR files, libraries, and configuration.
If you are using a shared library which is shared among multiple application which runs under different users then you may run into permission issue, like JAR file is owned by some other user and not accessible to your application.
One of our readers “it’s me said”, faced java.lang.NoClassDefFoundError due to this reason. See his comment also.
Typo on XML Configuration can also cause NoClassDefFoundError in Java. As most of Java frameworks like Spring, Struts they all use XML configuration for specifying beans. By any chance, if you put the bean name wrong, it may surface as java.lang.NoClassDefFoundError while loading other class which has a dependency on the wrongly named bean.
This is quite common in the Spring MVC framework and Apache Struts where you get tons of Exception in thread «main» java.lang.NoClassDefFoundError, while deploying your WAR or EAR file.
9) Another example of java.lang.NoClassDefFoundError, as mentioned by our reader Nick, is that when your compiled class which is defined in a package, doesn’t present in the same package while loading like in the case of JApplet it will throw NoClassDefFoundError in Java. Also, see Nick’s comment on this error.
10) java.lang.NoClassDefFoundError can be caused due to multiple classloaders in J2EE environments. Since J2EE doesn’t mention standard classloader structure and it depends on different vendors like Tomcat, WebLogic, WebSphere on how they load different components of J2EE like WAR file or EJB-JAR file.
In order to troubleshoot NoClassDefFoundError in the J2EE application knowledge of How ClassLoader works in Java is mandatory. Just to recap ClasLoader works on three principles delegation, visibility, and uniqueness.
Delegation means every request to load a class is delegated to the parent classloader, visibility means an ability to found classes loaded by the classloader, all child classloaders can see classes loaded by parent classloader, but parent classloader can not see the class loaded by child classloaders.
Uniqueness enforces that class loaded by the parent will never be reloaded by child classloaders. Now suppose if a class says User is present in both WAR file and EJB-JAR file and loaded by WAR classloader which is child classloader which loads the class from EJB-JAR. When a code in EJB-JAR refers to this User class, Classloader which loaded all EJB class doesn’t found that because it was loaded by WAR classloader which is a child of it.
This will result in java.lang.NoClassDefFoundError for User class. Also, If the class is present in both JAR file and you will call equals method to compare those two objects, it will result in ClassCastException as the object loaded by two different classloaders can not be equal.
11) Some of the readers of this blog also suggested that they get Exceptions in thread «main» java.lang.NoClassDefFoundError: com/sun/tools/javac/Main , this error means either your Classpath, PATH or JAVA_HOME is not setup properly or JDK installation is not correct. which can be resolved by reinstalling JDK?
If you are getting this error try to reinstall JDK. One of our readers got this issue after installing jdk1.6.0_33 and then reinstalling JDK1.6.0_25, he also has his JRE and JDK in a different folder. See his comment also by searching JDK1.6.0_33.
12) Java program can also throw java.lang.NoClassDefFoundError during linking which occurs during class loading in Java. One of the examples of this scenario is just deleted the User class from our static initializer failure example after compilation and they try to run the program.
This time, you will get java.lang.NoClassDefFoundError directly without java.lang.ExceptionInInitializerError and message for NoClassDefFoundError are also just printing the name of the class as testing/User i.e. User class from the testing package. Watch out for this carefully as here root cause is absent of User.class file.
java.lang.NoClassDefFoundError: testing/User
at testing.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:23)
Let me know how exactly you are facing NoClassDefFoundError in Java and I will guide you on how to troubleshoot it if you are facing something new way than I listed above we will probably document it for the benefit of others and again don’t be afraid with Exception in thread «main» java.lang.NoClassDefFoundError.
Other Exception and Error handling Tutorials from Javareivisted
- How to solve UnSupportedClassVersionError in Java
- Java.net.BindException: Address already in use: JVM_Bind:8080 Solution
- JDBC — java.lang.ClassNotFoundException: com.mysql.jdbc.Driver Solution
- How to Fix java.lang.classnotfoundexception oracle.jdbc.driver.oracledriver
- How to solve java.lang.ClassNotFoundException: org.Springframework.Web.Context.ContextLoaderListener
- How to fix java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
- How to solve java.lang.ClassNotFoundException: com.mysql.jdbc.Driver