Skip to main content

ClassNotFoundException

Every programmer would have encountered a ClassNotfoundException somewhere in the development lifecycle. Many times we search for reasons why this is happening and i have seen many times people spending long hours to find why this is happening. This is particularly seen with web applications which are deployed in a webserver like tomcat or an app server like Weblogic or JBoss.In the case of a normal desktop java application, this can be fixed by adding the required class or the library that contains the class to the classpath. This way with Java 1.2, classpath classloader will load the class and the issue is fixed.

For a web application this may not be as staightforward. Some times i have seen people adding the class to the classpath of the webserver and still getting the error again.

Now to identify and fix these issues we need to understand that java supports many types of classloaders. The main one being bootstrap classloader responsible for loading Java API. The other one is the classpath classloader responsible for loading the classes refered in the classpath of the java. In the case of web application , the webserver uses it own user defined class loader to load the classes from the WAR file. Based on java security architecture a class loaded by a classloader can only see classes loaded by it. Then you would wonder how did a userdefined classloader access classes loaded by the bootstrap classloader if it can only see classes loaded by it. This is not true. The classloaders follows a parent child delegation model. If user defined class loader (in this cases , the classloader who loads classes from WAR) is required to load a class it asks the classloader's parent to load it and the parent will ask its parent this chain goes on and if none of the parent can load then it is upto the userdefined classloader to load it and if it cannot load , classnotfoundexception occurs.

I will try to explain this with an example.

Consider the case of a WAR file in which Class A is included in the WAR file. Class A references Class B. But Class B is not included in the WAR file. Infact someone has added it to the classpath of the webserver for some reason. Hence when the web classloader loads Class A, it finds the reference to Class B and it tries to load Class B when the method which uses Class B is invoked on Class A. For this it will ask its immediate parent and finally it will be loaded by the classpath classloader and returned. No issues here. No ClassNotFoundException.

Consider the case in which Class A is put in the webserver's class path and Class B is included in the WAR file. Here when web classloader (classloader responsible for loading classes from the WAR file. ) is required to load Class A, it asks its immediate parent and the chain continues and finally Class A is loaded by the classpath classloader and is returned. Now since Class B is not loaded by classpath classloader and Class A is loaded by classpath classloader when the method which uses Class B is invoked on Class A, a ClassNotFoundException would be thrown.

This is because classpath classloader can only ask its parent to load class and not its child classloader. This means classpath classloader doesn't know about Class B loaded by the Web Classloader. The reverse is true. Web Classloader will have access to classes loaded by its parent.
To solve the above ClassNotFoundException put both classes in the WAR file . Another option is to put Class A in WAR and Class B in classpath.

Pointer : Include all classes in the WAR file. Don't put any application specific classes in the webservers classpath. The above example was taken just to explain the classloader working.


Comments

These are some of the subtlities with Application servers. In more complex cases you will get ClassCastException when try to use a object instantiated by one classloader in another classloader.

Popular posts from this blog

Using Database login Module in JBoss

This post is a detailed description on how to use the database login module in JBoss with a J2EE Application. Scenario There is a EJB and we want to restrict the access to this ejb's method to an authenticated user having a particular role. The EJB is accessed from a standalone Java Client using Remote Lookup. Implementation The EJB is HelloSSB and the roles allowed are admin and user. First step is to write the EJB The source code is given below. This is a stateless session bean. package com.prem.ejb; import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.annotation.security.RolesAllowed; import javax.ejb.SessionContext; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.jboss.annotation.security.SecurityDomain; @Stateless @SecurityDomain ("helloworld") public class HelloSSB implements HellioIntf{ @PersistenceContext(unitName = "EntApp") EntityManager em; @Reso...

Design Patterns

A note on Design patterns Many times we can see ourselves looking for design patterns to fit the design of a requirement. Of course if the requirement is simple enough to apply any existing design pattern we should do so. This will save us valuable time. In my opinion it is better not to worry about which pattern to apply.But concentrate on the three basic Object oriented principles. 1) Encapsulate what varies 2) Prefer composition over inheritance 3) Program to an interface not to an implementation. If we approach the design with these principles in mind , we don't have to search for patterns. Pattern will emerge itself. Once we apply these principles, we can definitely look whether any of the existing patterns can solve the issue better than the way we thought of. This way our thinking process will improve tremendously and at times we may end up creating a solution which may be better than any available design patterns.

Load Balancing

Why do you need to load balance ? Here i will put forward the various options available for web load balancing. Before we go into that , let us first examine why do we need load balancing after all.Consider you develop a website and is available to the public.If the application is served from a single webserver then there is a high chance that the machine will be overwhelmed if the usage of the application increases. This may result in users experiancing unusually high response times or in worse case the machine can come to a halt.So you need some mechanism to distribute the load across different machines,without the client having to swich address. There are many widely used approaches. The most common ones are DNS based load balancing Software load balancing Hardware load balancing DNS based Load Balancing Here the DNS server is configured in such a way that it returns different IP addresses for various requests to the DNS server for a particular domain name. The DNS server may contai...