3 ways to solve java.lang.NoClassDefFoundError in Java J2EE

from

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 couple of times and spent quite a lot time initially to figure out what is wrong , which class  is missing etc. First mistake I did was  mingling java.lang.ClassNotfoundException and NoClassDefFoundError, in reality they are totally different, and my second mistake was using trial and error method to solve this java.lang.NoClassDefFoundError instead of understanding why NoClassDefFoundError is coming, what is  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 which cannot be resolved or hard to resolve it’s just its manifestation which  puzzles most of Java developer. This is the most common error in  Java development along with  java.lang.OutOfMemoroyError: Java heap space and  java.lang.OutOfMemoryError: PermGen space   Anyway let’s see Why NoClassDefFoundError comes in Java and what to do to resolve NoClassDefFoundError in Java.



What is reason of NoClassDefFoundError in Java?

NoClassDefFoundError in Java comes when Java Virtual Machine is not able to find a particular class at runtime which was available during 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 throwNoClassDefFoundError. It’s important to understand that this is different than  ClassNotFoundException which comes while trying to load a class at run-time only and name was provided during runtime not on compile time. Many Java developer mingle 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 below line in log when you get NoClassDefFoundError:

Exception in thread "main" java.lang.NoClassDefFoundError

Exception in thread “main” simply indicate that its  “main” thread which is not able to find a particular class it could be any thread so just don’t worry . Difference between this error coming in main thread and other thread is , when Exception in thread “main” comes program crashes or shut it self down as opposed to other thread in which case your program will continue to run.,



Difference between java.lang.NoClassDefFoundError and ClassNotFoundException in Java

Many a times we confused ourselves with java.lang.ClassNotFoundException and java.lang.NoClassDefFoundError, though both of them related to Java Classpath they are completely different to each other. ClassNotFoundException comes when JVM tries to load a class at runtime dynamically means you give the name of class at runtime and then JVM tries to load it and if that class is not found in classpath it throws java.lang.ClassNotFoundException. While in case of NoClassDefFoundError the problematic class was present during Compile time and that's why program was successfully compile but not available during runtime by any reason. NoClassDefFoundError is easier to solve than ClassNotFoundException in my opinion because here we know that Class was present during build time but it totally depends upon environment, if you are working in J2EE environment than you can get NoClassDefFoundError even if class is present because it may not be visible to corresponding class loader. See my post  NoClassDefFoundError vs ClassNotFoundException in Java for more details.



How to resolve java.lang.NoClassDefFoundError in Java

java.lang.NoClassDefFoundError in Java solution Obvious reason of 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:

1) Class is not available in  Java Classpath.

2) You might be running your program using jar command and class was not defined in manifest file's ClassPath attribute.

3) Any start-up script is overriding Classpath environment variable.
4) Because NoClassDefFoundError is a sub class 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 failure of  static initialization is quite common.

5) If you are working in J2EE environment than visibility of Class among multiple Classloader can also cause java.lang.NoClassDefFoundError, see examples and scenario section for  detailed discussion.

We will now see couple of example and scenarios when java.lang.NoClassDefFoundError has came before and how its been resolved. This can help you to troubleshoot root cause of NoClassDefFoundError in Java application.


NoClassDefFoundError in Java - Example and Scenarios

1. Simple example of NoClassDefFoundError is class belongs to a missing JAR file or JAR was not added into classpath or sometime jar's name has been changed by someone like in my case one of my colleague has changed  tibco.jar into  tibco_v3.jar and by program is failing with java.lang.NoClassDefFoundError and I was wondering what's wrong.

2. Class is not in Classpath, there is no sure shot way of knowing it but many a 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 its working then it's sure short sign that  some one is overriding java classpath.


NoClassDefFoundError in Java due to Exception in Static Initializer block

This is another common reason of java.lang.NoClassDefFoundError, when your class perform some static  initialization in static block like many  Singleton classes initialized itself on static block  to take advantage of  thread-safety provided by JVM during class initialization process, and if static block throw 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 below code example, During class loading and initialization Userclass is throwing Exception from static initializer block, which trigger ExceptionInInitializerError during first time loading of User class in response to new User() call. Later rest of new User() are failing as java.lang.NoClassDefFoundError. 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 a  also a LinkageError which arises due to dependency on some other class , you can also get java.lang.NoClassDefFoundError if your program is dependent on native library and 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 ANT build file  create JAR and manifest file than its worth noting to debug till that level to ensure that  ANT build script is getting correct value of classpath and appending it to manifest.mf file.

7) Permission issue on JAR file can also cause NoClassDefFoundError in Java. If you are running your Java program in multi-user operating system like Linux than you should be using  application user id for all your application resources like JAR files, libraries and configuration. If you are using shared library which is shared among multiple application which runs under different users  then you may run with permission issue , like JAR file is owned by some other user and not accessible to your application. One of our reader “it’s me said” faced java.lang.NoClassDefFoundError due to this reason. See his comment also.

8) Typo on XML Configuration can also cause NoClassDefFoundError in Java. As most of Java frameworks like  SpringStruts 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 dependency on wrongly named bean. This is quite common on 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 same package while loading like in 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 class-loader structure and it depends upon 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 J2EE application knowledge of  How ClassLoader works in Java is mandatory. Just to recap ClasLoader works on three principle delegation, visibility and uniqueness. Delegation means every request to load a class is delegated to parent classloader, visibility means ability to found classes loaded by classloader, all child classloader can see classes loaded by parent classloader but parent classloader can not see the class loaded by child classloaders. Uniqueness enforce that class loaded by parent will never be reloaded by child clasloaders. Now suppose if a class say User is present in both WAR file and EJB-JAR file and loaded by WAR classloader which is child classloader which loads class from EJB-JAR. When a code in EJB-JAR refer to this User class, Classloader which loaded all EJB class doesn’t found that because it was loaded by WAR classloader which is child of it. 

This will result in java.lang.NoClassDefFoundError for User class. Also If class is present in both JAR file and you will call  equals method to compare those two object, it will result in ClassCastException as object loaded by two different classloader can not be equal.


11) Some of reader of this blog also suggested that they get Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/javac/Main , this error means either your  ClasspathPATH  or  JAVA_HOME is not setup properly or JDK installation is not correct. which can be resolved by re-installing JDK. IF you are getting this error try to reinstall JDK . One of our reader got this issue after installing jdk1.6.0_33 and then reinstalling JDK1.6.0_25, he also has his JRE and JDK on 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 example of this scenario is just delete 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.NoClassDefFoundErrordirectly without   java.lang. ExceptionInInitializerError and message for NoClassDefFoundError is also just printing name of class as testing/User i.e. User class from 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 how to troubleshoot it, if you are facing with something new way than I listed above we will probably document if for benefit of others and again don’t afraid with Exception in thread "main" java.lang.NoClassDefFoundError.  


Other Exception and Error handling Tutorials from Javareivisted
Read more:  http://javarevisited.blogspot.com/2011/06/noclassdeffounderror-exception-in.html#ixzz3aZDT3ePe

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值