Saturday, August 20, 2011

How to resolve java.lang.ClassNotFoundException in Java

What is ClassNotFoundException in Java
ClassNotFoundException is one of Java nightmare every Java developer face in there day to day life. java.lang.NoClassDefFoundError and java.lang.ClassNotFoundException are two errors  which occurs by and now and chew up of your precious time while finding and fixing root cause. From the name java.lang.ClassNotFoundException looks quite simple but underlying cause of it is always different and which classifies it as an environmental issue. In this java tutorial we will see what is ClassNotFoundException in java, what is real cause of it and how to fix it along with some more frequent and infamous examples of java.lang.ClassNotFoundException in Java or J2EE, Don’t mistake this exception with NoClassDefFoundError in Java which is also due to incorrect classpath in Java.  Though both of them are related to missing class file when Java tries to load class in Java they are completely different to each other.  Correct understanding of  When class is loaded in Java and How Classpath works  is must to troubleshoot and fix this error quickly.


What is java.lang.classNotFoundException in Java

As the name suggests classNotFoundException in Java is a subclass of java.lang.Exception and Comes when Java Virtual Machine tries to load a particular class and doesn't found the requested class in classpath. Another important point about this Exception is that, It is a checked Exception and you need to provide explicitly Exception handling while using methods which can possibly throw classnotfoundexception in java either by using try-catch block or by using throws clause. Though underlying concept of this exception is simple but it always manifest itself in such format that you need to spend some time to figure out what exactly wrong with your classpath. If you want to know nasty secrets of java classpath  which can cause issue see the link

When ClassNotFoundException occurs in Java:

As per java doc java.lang.classNotFoundException comes in following cases:

1) When we try to load a class by using Class.forName() method and .class file or binary of class is not available in classpath.
2) When Classloader try to load a class by using findSystemClass () method.
3) While using loadClass() method of class ClassLoader in Java.

What is ClassNotFoundException in Java - Fix SolutionThese statements are completely true in terms of theory of ClassNotFoundExcepiton in Java but as per my experience the concept is "ClassNotFoundException will come only when JVM tries to load a class at run-time, nothing related to compile time unlike NoClassDefFoundError". Also since till run time JVM doesn't know about this Class it can only be done by above specified method or by employing Reflection to read the name of class from some configuration file like in case of struts its struts-config.xml file and then load the class specified on those configuration file. Reflection is great power of Java but you need to be aware of java.lang.classNotFoundException while using it or loading class in Java.


Examples of classnotfoundexception in java

Though java.lang.classNotFoundException is very common and it can come for any classes, I usually see it while doing JDBC connectivity like when I was writing Java program to connect Oracle database. I am going to list some of the most common scenario where you will get classnotfoundexception in java.

java.lang.classnotfoundexception com.mysql.jdbc.driver

This is classical and most infamous example of  and also my first encounter with java.lang.ClassNotFoundException and comes when you are writing JDBC connectivity code and trying to load the JDBC driver. In this particular case of ClassNotFoundException looks like mysql driver jar file is missing from Classpath. If you pay attention you will find that we use method Class.forName (“driver”) to load the driver class which resides in a particular jar in case of this its mysql-connector.jar and if that jar is not in classpath or not accessible to JVM it will throw  java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

Here are few more infamous examples of java.lang.ClassnotFoundException which comes here and there while doing any Java J2EE project. 
java.lang.classnotfoundexception org.hibernate.hql.ast.hqltoken
java.lang.classnotfoundexception org.springframework.web.context.contextloaderlistener
java.lang.classnotfoundexception org.eclipse.core.runtime.adaptor.eclipsestarter
java.lang.classnotfoundexception org.apache.catalina.startup.catalina
java.lang.classnotfoundexception javax.mail.messagingexception
java.lang.classnotfoundexception oracle.jdbc.driver.oracledriver

This ClassNotfoundException comes when you are trying to connect Oracle database from Java program using JDBC but you don't have corresponding Oracle driver e.g.ojdbc6.jar is not in classpath of your Java program

More Complicated ClassNotFoundException

With the advent of dynamic library e.g. OSGi and ClassLoader in Java, this exception can be more tricky and hard to find. Thanks to Mr. Anonymous who has summarized this beautifully, here it is what he says
“It can become a bit more complicated than that. In truth a class does not have to be just visible by the JVM through its classpath, but be visible by the Classloader being used. When you are in a multi-classloader environment (In a EE environment, for example, but not limited to), each classloader may have its own rules to search for the classes, and this behavior might depend on the dynamic hierarchy of the Classloaders.
For example, in a project that uses an EAR packaging with WARs inside it, libraries in the lib folder of the EAR are visible to classes inside a WAR, but any classes packaged in a jar put in the WEB-INF/lib on the WAR cannot be seen by classes in different modules (other WARs, EJB-JARS, etc).
It can get really complicated as its common for different modules depending on different versions of the same libraries as different modules depend on each other. It can be a challenge to manage this. Sometimes the classloader can see multiple versions of the same class; sometimes they can see no version at all. Sometimes different dependency paths end in different versions of the same class. And many of this cases end in a ClassNotFoundException.
And then we have OSGi... “. If a class is not visible to ClassLoader than it can also throw NoClassDefFoundError in Java as explained in  3 ways to resolve NoClassDefFoundError in Java.

How to fix java.lang.ClassNotFoundException in Java
As you have seen from above examples its clear problem of classpath, so here is
my approach to fix or resolve java.lang.ClassNotFoundException:

1) First find out the jar file on which problematic class file is present for example in case of "
com.mysql.jdbc.driver" its mysql-connector-java.jar. If you don't know how to find which jar file a particular class you can see eclipse shortcuts to do that or you can simply do "Ctrl+T" in Eclipse and type the name of class, It will list all the jar in the order they appear in eclipse classpath.

2) Check whether your classpath contains that jar, if your classpath doesn't contain the jar then just add that class in your classpath.

3) If it’s present in your classpath then there is high chance that your classpath is getting overridden or application is using classpath specified in jar file or start-up script and to fix that you need to find the exact classpath used by your application.


Live example of reproducing and Fixing ClassNotFoundException in java
I think if we are able to reproduce and solve certain problem we become more comfortable dealing with that, that’s why here we will reproduce java.lang.ClassNotFoundException and solve it by following the concept we have discussed so far.

1)
Create a Class called StockTrading.java

public class StockTrading{
   public String getDescription(){
   return "StockTrading";
  }
}


2)
create a Class called OnlineStockTranding.java and load the class StockTrading.java as Class.forName ("stocktrading");

public class OnlineStockTrading {
   public static void main(String args[]) throws ClassNotFoundException{
      Class.forName("StockTrading");
      System.out.println("StockTrading class successfully loaded");
   }
}

3) Compile both Java source file which will create two class files and run the program should run fine.

javin@trading~/java:
javac *.java

javin@trading ~/java:
ls –lrt
-rw-r--r-- 1 javin None  90 Aug 21 09:27 StockTrading.java
-rw-r--r-- 1 javin None 208 Aug 21 09:28 OnlineStockTrading.java
-rwxr-xr-x 1 javin None 282 Aug 21 09:28 StockTrading.class
-rwxr-xr-x 1 javin None 638 Aug 21 09:28 OnlineStockTrading.class

javin@trading ~/java:$
java OnlineStockTrading
StockTrading class successfully loaded


4) Now just
remove the .class file for stocktrading.java and run the Java program and it will throw java.lang.ClassNotFoundException in java.

javin@trading ~/java:
rm StockTrading.class

javin@trading ~/java:
java OnlineStockTrading
Exception in thread "main" java.lang.ClassNotFoundException: StockTrading
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)



ClassFoundException vs NoClassDefFoundError vs UnSupportedClassVersionError
There are lots of exceptions in java but these three are the one who most haunted the java developer most mainly because these three are mostly related to environment issues and they all depends upon JVM and Classpath behaviour. Though they look similar there is slight difference between ClassFoundException and NoClassDefFoundError and UnSupportedClassVersionError and we will highlight those differences here for easy understanding and differentiating these three:

1)
ClassNotFoundException comes on Runtime when requested class is not available in classpath and mainly due to call to Class.forName () or Classloader.loadClass () or ClassLoader.findSystemClass ().

2)
NoClassDefFoundError comes when problematic class was present when your compiled your application but they are not in classpath while you running your program.

3)
UnSupportedClassVersionError is easy to differentiate because it’s related to version of classpath and usually comes when you compile your code in higher Java version and try to run on lower java version. Can be resolved simply by using one java version for compiling and running your application.

So that's all on
ClassNotFoundException in java for now , please let me know if you have any tip or  any personal experience on solving java.lang.ClassNotFoundException in Java which you would like to share.


Some more Interesting tutorials:

12 comments :

Anonymous said...

good approach to solve java.lang.ClassNotFoundException.I agree no matter how much you know about ClassNotFoundException when it comes it takes some time to figure out.

Anonymous said...

In it can become a bit more complicated than that. In truth a class does not have to be just visible by the JVM through its classpath, but be visible by the Classloader being used. When you are in a multi-classloader environment (In a EE environment, for example, but not limited to), each classloader may have its own rules to search for the classes, and this behavior might depend on the dynamic hierarchy of the Classloaders.
For example, in a project that uses an EAR packaging with WARs inside it, libraries in the lib folder of the EAR are visible to classes inside a WAR, but any classes packaged in a jar put in the WEB-INF/lib on the WAR cannot be seen by classes in different modules (other WARs, EJB-JARS, etc).
It can get really complicated as its common for different modules depending on different versions of the same libraries as different modules depend on each other. It can be a challenge to manage this. Sometimes the classloader can see multiple versions of the same class, sometimes they can see no version at all. Sometimes different dependency paths end in different versions of the same class. And many of this cases end in a ClassNotFoundException.
And then we have OSGi...

Kapil Viren Ahuja said...

You picked up the right pain area but your example is simply not adequate enough. You are talking about issues in a very simple environment like a Java application. In enterprise applications where we have tools like Maven to build programs, the approach to manage dependencies are not that simple. You have to be aware of what is being used how. A simple example would be - you use a local data source and a DB pooling using DBCP in testing, however when you deploy on a web/app server you cant not use the same data source because you want to read from a JNDI. Hence the scope of DBCP is not needed in production.

It may not throw an exception with an additional include, but in some cases like logging where most app server provide their own Jars if you provide your jars with an incomparible version, the app server itself will use the jar you provide and the a simple logging statement will throw a different exception.

In addition, ClassLoader playes a very important role in this entire scheme of things. In most cases we use the default class loader, when the moment you do into EE world you are in for a surprise.

Reflection is much simpler problem to solve. In most cases, you know what you are loading - we do not use extensive reflection on a framework classes. We need reflection to handle our own logic and in that case we own the classes. When we compile our code we do not omit one class by removing a class file (unless scripts are written wrong).

Try working with XML, JMX, JMS and classloader / classnotfound are a different ball game

Javin @ convert string to int in java said...

Thanks Kapil for your valuable input.you are right J2EE is different ball game with sheer use of Classloaders implemented by different web or enterprise server and it could result in more pain if we simply occupied with the classical manifestation of ClassNotFoundException. though in my opinion refective version of ClassNotFoundException is little easier to solve than due to ClassLoaders whether its originated from framework configuration or direct because mostly that due to either spelling mistake or simple case of Classpath issue. Once again thanks for your kind comment and pointing discussion to an important direction.

saru said...

Nov 8, 2011 3:55:36 PM org.apache.struts.actions.DispatchAction dispatchMethod
SEVERE: Dispatch[/dataentry] to method verification returned an exception
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:280)
at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:216)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:507)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/Signature
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at carrent.action.loginverify.verification(loginverify.java:35)
... 24 more
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.Signature
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1358)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 27 more

Jinny said...

ClassnotFoundException is not that bad, its still better than OutOfMemory, unsupportedClassVersionError and NoClassDefFoundError which took hell lot of time to debug and find the root cause. At least with ClassNotFoundException you know that a particular Class is not available at runtime.

Anonymous said...

i got message frequently in my phone as 'plese chech your interconnection java.lang.nullpointerexception'. i cant fix that proble. anybody plese help me

Anonymous said...

I am 16, and dont understand this stuff i want to fix this cause i play runescape, and i cant play with this error popping up everytime i try to play the game please send me a email telling me how to fix this at codx96@gmail.com Please.

1 said...

Well every java stuffs in my browser is giving me this. This start when I clean install new os Win 8 pro 64 bit.

From Java 7 U9 and now Java 7 U10 I still can't use Java. I thought U10 is where Win 8 support starts. Emailing Java ppl gets no response.

Anonymous said...

I cant start up any yahoo games as soon as I go in and java is suppose to bring up applet it fails and gives me an error any help would be appreciated

Sanjay Patel said...

Why are we using Class.forName("nameofclass"); As we know before running any java program all the files are getting loaded then in between why we are loading class by Class.forName().

Milan Grujić said...

Have the same problem. Uninstalled the java 7 , restart the computer , download latest java6 , installed it and works fine now.

Post a Comment