7 Replies Latest reply on Nov 23, 2002 6:41 AM by bpowell

    Classloader rules... what are they?

      I have a stateless session bean that needs to look up a class via a Class.forName call.

      However, whenever I try it I get a class not found exception:

      java.lang.ClassNotFoundException: com.dsicdiiti.tnt.demo1.search.SearchCommand
      at org.jboss.mx.loading.UnifiedLoaderRepository.loadClass(UnifiedLoaderRepository.java:152)
      at org.jboss.mx.loading.UnifiedClassLoader.loadClass(UnifiedClassLoader.java:285)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
      at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:310)
      at java.lang.Class.forName0(Native Method)
      at java.lang.Class.forName(Class.java:115)


      If I change the line from

      return Class.forName("com.dsicdiiti.tnt.demo1.search.SearchCommand");

      to

      com.dsicdiiti.tnt.demo1.search.SearchCommand cls = new com.dsicdiiti.tnt.demo1.search.SearchCommand();
      return cls.getClass();

      it works just fine. However, I can't use this solution since the actual class name will not be known until runtime.

      How do i configure the class loader to find the class I need?

      Thanks!

        • 1. Re: Classloader rules... what are they?
          tbfmicke

          I read somewhere that you should use the context classloader from the thread you are in.
          So you could try the following:

          ClassLoader loader = Thread.currentThread().getContextClassLoader();
          Class theClass = loader.findClass(TheClassName);

          Disclaimer: I'm not sure if this will work, and if it works I'm not sure about the exact reason why it works :-)

          Regards

          • 2. Re: Classloader rules... what are they?

            Well, thanks for the suggestion, but it didn't work. I still got the ClassNotFoundException

            Incidentially, i had to change:

            Class theClass = loader.findClass(TheClassName);

            to

            Class theClass = Class.forName(TheClassName,true,loader);

            because findClass is protected.

            Back to the drawing board, anyone else have any suggestions?

            • 3. Re: Classloader rules... what are they?

              hi,

              I was also wrestling with classloaders, and I had to dig deep into the secrets of classloaders, and now I can use them good enough.

              One thing I just guess:
              (1) The class you want to load is located in your EJB jar or ear or (2) you want to load from a different location (eg. an external jar)

              If it is the 1. case, I don't really know why it throws ClassNotFoundException. In fact, I tried it, and it worked.

              If it is the 2. case, you should use something like this:

              ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
              try {
              URLClassLoader classloader = URLClassLoader.newInstance(
              new URL[]{new URL(classPath)}, Thread.currentThread().getContextClassLoader());
              Thread.currentThread().setContextClassLoader(classloader);

              Class c = classloader.loadClass(className);

              return c.newInstance();
              } finally {
              Thread.currentThread().setContextClassLoader(oldCL);
              }

              sorry for the ugly formatting, but whitespaces are removed.

              So, I use this code loading a class from a jar file that is located on a http server.

              • 4. Re: Classloader rules... what are they?

                by the way,
                you should check this. very good stuff how jboss classloaders works:

                http://www.jboss.org/modules/bb/index.html?module=bb&op=viewtopic&t=forums/

                • 5. Re: Classloader rules... what are they?

                  Thanks for all the advice. I ended up not being able to get the Class.forName call to work while within the bean method, so I just moved the functionality to a class earlier up the chain and passed the Class object to the bean. Oh well. It isn't the cleanest, but I have to move on!

                  • 6. Re: Classloader rules... what are they?
                    kashpaw

                    I assume the class resides in some non-standard location (i.e. not in an archive in the lib or deploy directories). If that's the case, you can specify the location in the configuration of the first mbean in jboss-service.jar.

                    • 7. Re: Classloader rules... what are they?
                      bpowell

                      Mipe,
                      regarding slsb and classloading,
                      2 questions:
                      If you use classforname or get a new instance of any class in this stateless bean, can the container manage transactions in this class?
                      If we use the thread's classloader can we guarantee we are thread safe in the new class?