3 Replies Latest reply on Dec 31, 2002 10:45 AM by Adrian Brock

    Global instance across applications?

    Alexander Hristov Newbie

      Hello,

      I'm using JBOSS 3.0.0 and I've a configuration problem and I think I have solved it, but I'd like to know
      your opinion.

      I need several objects to be global (unique across applications and virtual hosts). These objects control pools and other wierd stuff. The objects are written using the Singleton pattern (private constructor, static factory method etc...).

      Well, to the point: If I package all this stuff in a .jar file and place it in the lib\ directory of each web application, then multiple "Singleton" instances are created. I guessed that this might be because of the classloader, which may be thinking that class A in foo.jar in webapp is not the same as class A in foo.jar in a different webapp.

      So the next thing I did was to remove all these copies of the jar and modify the JBOSS_CLASSPATH variable to point to a single .jar. But then during startup I'm getting errors like java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet. How is this possible? So I hunt down the jar containing these interfaces (javax.servlet.jar) and add it to the JBOSS_CLASSPATH varible.


      Now is this the right thing to do?

        • 1. Re: Global instance across applications?
          Adrian Brock Master

          Don't put things in the classpath.

          If you have the singleton in lib why does having
          the user in multiple webapps create duplicates?
          There should only be one classloader for jars in lib.

          Regards,
          Adrian

          • 2. Re: Global instance across applications?
            Alexander Hristov Newbie

            > Don't put things in the classpath.
            >
            > If you have the singleton in lib why does having
            > the user in multiple webapps create duplicates?
            > There should only be one classloader for jars in
            > lib.
            >
            > Regards,
            > Adrian

            Yes, that the theory, but there seems to be some boundary. Here is a simple setup that demostrates this:

            First the bare-bones singleton class (very trivial):

            package planetalia;

            public class Singleton {
            public static Singleton instance = null;

            private Singleton() {
            System.out.println("Constructor called.");
            }

            public static Singleton getSingleton() {
            if (instance == null)
            instance = new Singleton();
            return instance;
            }
            }

            Now set up two different enterprise applications with one web module each, accessible using two different virtual hosts. Compress the above class into a jar and place it
            in the lib folder of both web apps. Also, in the root dir of each web app place the following test jsp:

            <%@ page import="planetalia.Singleton" %>

            Existing instance = <%= Singleton.instance %>
            Trying to get a singleton:
            <%
            Singleton single = Singleton.getSingleton();
            %>


            Now if you access the first web app, the first time you call this jsp the existing instance will be null (as expected) and the constructor will be called, and it will print "Constructor called" on stdout. If you call the jsp some more times, the constructor will not be called and an existing instance will print (also as expected).

            However, things change if you now access the other web app (located in the second enterprise application). The JSP will tell you that the instance does not exist, the constructor will be called again AND a new different object will be created (if you look at the hashcode that gets printed)

            So I guess different enterprise apps have different classloaders, but is there any better way (other than altering the JBOSS_CLASSPATH variable) of getting this effect? (BTW I was using JBoss 3.0.4 and not 3.0.0, and things get worse since I use other J2EE components and it seems that I will end putting everything in the classpath)

            Many thanks in advance....

            Alexander

            • 3. Re: Global instance across applications?
              Adrian Brock Master

              When I said lib i meant
              server/default/lib

              WEB-INF/lib has one classloader for
              each web-app

              Regards,
              Adrian