1 2 Previous Next 18 Replies Latest reply on Sep 26, 2005 10:34 AM by jaikiran

    War Classloader Issue

    majohnst

      I have been around the block about ten thousand times, and my classloader issues just won't go away. (JBoss 4.0.2)

      I have some common classes that I use, so I put myCommon.jar inside server/lib. I put my webapp classes in webapp/WEB-INF/lib/myApp.jar The classes from my webapp access those common classes.

      I have tried to turn on ClassLoaderIsolation, (using the instructions on the Wiki) so I can get log4j to work correctly. Now when I try to start my app, my webapp says that it can't find the classes that are in myApp.jar

      From what I can tell, I have a Listener defined in my web.xml, say Listener1. The Listener1 file is located in myCommon.jar file. When started, Listener1 will call classes in myApp.jar. Is this causing the problem of the Class not found? Since one file is located on the server level and another at the webapp level, do they have different classloaders? Is there a way around this?

        • 1. Re: War Classloader Issue
          jaikiran

          Have a look at the section:

          Why is It Different? The Concept of Classloaders

          at the following link:

          http://www.onjava.com/pub/a/onjava/2003/04/02/log4j_ejb.html?page=last&x-maxdepth=0

          This might help in understanding the concept of classloader.

          Briefly explaining, your classes are not yet loaded by your Application Classloader, at the time when the classes are being reffered(i guess by your Listener1)

          • 2. Re: War Classloader Issue
            majohnst

            If I use Classloader Isolation for a war, does that mean that all the classes it accesses must be under WEB-INF/lib? I cannot mix classes from WEB-INF/lib and server/lib because they have different classloaders?

            • 3. Re: War Classloader Issue
              jaikiran


              "majohnst" wrote:
              Now when I try to start my app, my webapp says that it can't find the classes that are in myApp.jar


              I assume by this you mean ClassNotFoundException. Reason why this is occuring may be(again assuming that this class is present in the jar), the ClassLoader that you have defined for your application hasnt yet started at the time when this specific class is being reffered

              As far as, accessing classes that are present in a jar under server/lib from classes under WEB-INF/lib, is concerned, you can do that without any problems.

              Please post the exception that you are seeing.



              • 4. Re: War Classloader Issue
                majohnst

                Here is the error message. My war file is conman.war

                In my web.xml, I am trying to load this listener.

                <listener>
                <listener-class>rupurt.lifecycle.RupurtApplicationLifecycleListenerJBoss</listener-class>
                 </listener>



                09:24:56,019 INFO [TomcatDeployer] deploy, ctxPath=/conman, warUrl=file:/z:/conman/deploy/conman.war/
                09:24:58,035 FATAL [ComponentConfiguration] Cannot load class : com.pga.conman.jobs.PersistantJobScheduler
                java.lang.ClassNotFoundException: No ClassLoaders found for: com.pga.conman.jobs.PersistantJobScheduler
                 at org.jboss.mx.loading.LoadMgr3.beginLoadTask(LoadMgr3.java:198)
                 at org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java:475)
                 at org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:377)
                 at java.lang.ClassLoader.loadClass(Unknown Source)
                ....
                


                The class that is not being found is in a war file under WEB-INF/lib. Since the listener is being loaded during the webapp initialization, shouldn't the webapp classloader have already loaded the classes under WEB-INF/lib?

                • 5. Re: War Classloader Issue
                  jaikiran

                  Ya you are right, the webapp classloader should have loaded your class file, since control has already reached the webapp.
                  I am not sure whether that jar file containing the class, is ever getting loaded

                  Try out the following, not sure whether this might work:

                  In the MANIFEST.MF file in the META-INF folder of your conman.war include the following line:

                  Class-Path: yourApp.jar


                  where yourApp.jar is the name of the jar containing the class that is not found.

                  • 7. Re: War Classloader Issue
                    raja05

                    When you scoped the classloader for ur war, you might also have to set the java2ParentDelegation to be true. this property is by default set to false, and so when if the value is false, a NoParentClassLoader gets assigned as its parent class loader. When the class in the server/lib gets loaded and it requests for a class, you might want to let the server know that it should search the WEB-INF/lib also at that time by setting java2ParentDelegation to be true.
                    And, no, i dont think Jboss loads classes in the WEB-INF/lib during deployment. All classes are loaded when required and then added to the repository cache.

                    • 8. Re: War Classloader Issue
                      majohnst

                      Well I figured out my missing class issue. In some of the classes under server/lib, I used Class.loadClass. If I changed that the Thread.getCurrentThread().loadClass it worked.

                      But now I still haven't gotten log4j to work. I am trying to use a custom log4j.xml inside my WEB-INF/classes, but it's not working.

                      Has anyone gotten multiple log4j configurations to work?

                      • 9. Re: War Classloader Issue
                        jaikiran

                        Have a look at the "Using your own log4j.xml file - class loader scoping" section at :

                        http://www.jboss.org/wiki/Wiki.jsp?page=Logging

                        • 10. Re: War Classloader Issue
                          majohnst

                          I've read over the Wiki Loggin page tons of times, but I still haven't gotten it working. I renamed the conf/log4j.xml file to jboss-log4j.xml and editted the jboss-service.xml file accordingly. Then I added my custom log4j.xml in my WEB-INF/classes. In my custom log4j file, I put a different logging pattern and appenders from the ones in the conf/jboss-log4j.xml. But no matter what I do, it seems like my custom log4j.xml is never loaded.

                          • 11. Re: War Classloader Issue
                            jaikiran

                            Have you placed log4j.jar in your WEB-INF/lib folder?

                            • 12. Re: War Classloader Issue
                              jaikiran

                              I had tried out with .ear packaging with a .war inside it. That had worked for me.

                              • 13. Re: War Classloader Issue
                                majohnst

                                I haven't tried the ear. I have tried the RepositorySelector example from the Wiki, it it worked a little. I did get my custom logging configuration, but then I noticed that two of my webapps were cross-logging to each other. The log statements from one app would appear in the output log file of a different app.

                                • 14. Re: War Classloader Issue
                                  majohnst

                                  To clarify, I have used the RepositorySelector before I enabled classloader scoping and that worked. But when I enable classloader scoping, the RepositorySelector breaks with the error:

                                  java.lang.NullPointerException
                                   at java.util.Hashtable.put(Unknown Source)
                                   at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurator.java:141)
                                   at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfigurator.java:153)
                                   at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOMConfigurator.java:415)
                                   at org.apache.log4j.xml.DOMConfigurator.parseRoot(DOMConfigurator.java:384)
                                   at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:783)
                                   at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:678)
                                   at rupurt.logging.LogRepositorySelector.loadLog4JConfig(LogRepositorySelector.java:75)
                                   at rupurt.logging.LogRepositorySelector.init(LogRepositorySelector.java:56)
                                  


                                  1 2 Previous Next