Overview of ClassLoading Issues


    Why another page on classloading? Because sometimes when something is explained in a different way with different emphasis it is exactly what somebody needs for their problem.






    I get ClassNotFoundException


    This means that some dynamic classloading, i.e. classloader.loadClass() cannot find the class. This FAQ deals with the problem.


    I get NoClassDefFoundError


    This means that some JVM initiated classloading failed. Usually because of an import on an another class that was in the process of being loaded. Again this FAQ deals with the problem.



    I get ClassCastException


    There are some places where it reports this when it really means ClassNotFoundException, e.g. the CORBA



    Assuming it is the same class name, this problem relates to classes getting loaded from different

    classloaders. At compile time your class has only one identity, its name. If you "deploy" a class many times in different jars, it has multiple identities. They are not the same. See below for more information on the solutions to this problem.


    This can also be caused by you only redeploying part of your application. e.g. a webapp uses an EJB

    and you only redeploy the EJB. The webapp will still have the old versions of the classes.


    I get LinkageError


    Assuming you are running the version of the class you compiled over, this is a subtle form of ClassCastException when classes are passed between classloaders without doing a cast. e.g. you have a class in two separate deployments and you invoke a method that passes an object from one to the other but using an interface that the class implements. (See chapter 2 of the admin docs for more information of this subtle problem).


    I get ClassCircularityError


    Assuming this isn't a real circular reference, this is caused by a JDK bug. The solution is to avoid concurrent classloading for this class and probably related classes






    What are the types of things you want to do with classloading?


    Sharing and isolation




    The most common thing to do is to share classes. i.e. choose one version of the classes, test it and let everybody use it. This is usually the easiest to manage, understand and it is certainly the most efficient in terms of resources. It also directly mirrors your build environment.




    You don't want to share your classes with others but you do want to share common classes and use application server provided classes.


    JavaSE Spec compliance


    Related to sharing and isolation. Do you want to use application server classes where provided?


    Non Spec compliance (except the servlet spec


    You don't want to use application server classes or any shared classes. You want your own version.


    Caller semantics


    Call by reference


    This is probably what you are familiar with one java class invokes a method on another.


    Call by value


    This simulates a remote invocation over the network. Parameters are "marshalled" - turned into a byte stream - then "unmarshalled" with destinations classloader. Any return value or exception is again "marshalled" then "unmarshalled" with the origin's classloader.


    NOTE: You cannot use call-by-value for EJB local invocations. It simulates a remote call.








    If you choose not to share you will have problems talking to other applications that don't have the same version of the class. The solution is to use call-by-value to "translate" the classes between the classloaders.


    Spec compliance


    If you choose not to use the application server classes, you will have problems talking to the application server itself.


    Call by value


    The extra work of object to bytestream translation is a cpu overhead. Typically you will need 10 times the cpu power (or 10 times the number of machines to run compared to an application that uses call-by-reference.


    Servlet configuration


    The servlet spec says that you shouldn't use JavaSE spec compliance. This essentially means it will use anything you put in




    . Since these are usually "dumping grounds" for all sorts of "rubbish", this is usually a bad idea.


    This isn't quite true since there is a configurable filter to ignore certain packages.


    If you do want isolation, then configure that and share the application server classes.




    If you share classes with another application, make sure you either don't redeploy the shared classes or you redeploy everybody when they change.






    Share everything


    This is the default as long as you turn off the servlet spec classloader.


    EAR Deployer - ease of use






    on the



    enabling call-by-value for jndi will give you isolation and class translation for any applications deployed as ears.


    Listing an deployment's contents

    If you are relying on a jars ClassPath manifest header to pickup classes, its useful to display an overview of the archive contents including the ClassPath references. The attached ListJar, ListJar.class can be used for this. Run the ListJar program passing in the archive to list. For example:

    [starksm@banshee9100 main]$ java -cp . ListJar cpmanifest.ear
    +- abstract.jar (archive)
    |  +- org/jboss/test/jmx/loading/AbstractBean.class
    +- concrete.jar (archive)
    |  +- META-INF/MANIFEST.MF Class-Path: ./abstract.jar
    |  +- org/jboss/test/jmx/loading/Concrete.class
    |  +- org/jboss/test/jmx/loading/ConcreteBean.class
    |  +- org/jboss/test/jmx/loading/ConcreteHome.class
    |  +- META-INF/ejb-jar.xml
    +- META-INF/application.xml

    This shows that the cpmanifest.ear/concrete.jar includes the abstract.jar via its Class-Path.




    The mechanisms for each deployment type are explained in the main classloading configuration link


    More complicated


    Sometimes you want isolation, but you still want to share amongst a select number of applications. To do this, assign them to same classloader repository with a specific name of your choosing, rather than using the automatic one created by


    on the EARDeployer. This way you have your own little world to "play in".