5 Replies Latest reply on Oct 14, 2008 3:51 AM by prat Bhat

    No ClassLoaders found for: ClassLoading problem in JMS MDB s

    Anand Vidyasagar Newbie

      Hi,

      I have a bunch of In-Memory generated beans. (Using ASM to do a lot of the bean-generations)

      These Beans are passed on to the MDB's as Object messages and at a point when I call myMessageObject.getObject() it fails with the exception which says

      15:31:43,847 INFO [STDOUT] javax.jms.MessageFormatException: ClassNotFoundException: No ClassLoaders found for: com.xxx.yyy.zzz.SomeBean.
      15:31:43,847 INFO [STDOUT] at org.jboss.mq.SpyObjectMessage.getObject(SpyObjectMessage.java:136)


      If I try to see the result of Class.forName("com.xxx.yyy.zzz.SomeBean") before the line
      myMessageObject.getObject() I can see that the Object gets loaded. (My Eclipse debugger shows me the Class)

      I tried to debug it a little bit and am unable to proceed further. Seems like we call the Classes.loadClass(String name) that uses the current threads contextClassLoader().

      Should it not be using one of the RepositoryClassLoaders???
      Is this a bug Or a configuration mistake at my end.

      The classes that are held in the MessageObject are generated in memory and were loaded by another ESB.

      Please let me know if there any other information needed... I need some expert help on this one

        • 1. Re: No ClassLoaders found for: ClassLoading problem in JMS M
          Anand Vidyasagar Newbie

          Just forgot to mention
          Jboss version is: 4.0.3SP1

          • 2. Re: No ClassLoaders found for: ClassLoading problem in JMS M
            Adrian Brock Master

            The behaviour is correct.

            Class.forName() is a bad classloading api that shouldn't be used except
            in the most trivial of environments.

            You need to figure out why your generated class
            is not visible from the context classloader (the classloader of the MDB).

            Most likely because you've created your own classloader that is invisible
            from the rest of the classloading system or something like this?
            http://jira.jboss.org/jira/browse/JBAS-3691
            i.e. you used a backdoor to defineClass() on a classloader
            that never invokes findLoadedClass()
            (like IBM started doing with their proxy generation).

            • 3. Re: No ClassLoaders found for: ClassLoading problem in JMS M
              Anand Vidyasagar Newbie

              Thats correct... we are infact using the defineClass()

              Is there a way still to make this class available to the RepositotyClass loader.

              By the way the classLoader instance that I get at the point of time when I generate my code is an instance of the GenericClassLoader.

              Are there any other alternatives cos all we have is bytes[] of the class file at the time when we load these classes in memory.

              Earlier my code called defineClass on the currentClass.class.getClassLoader()

              I have changed the implementation to use the Thread.currentThread().getContextClassLoader().

              No luck here... I get the NoClassLoaders found for error in the first Try Catch.

              Here is how the code looks like now

              private Class createClass(ClassWriter writer, String className,
              String baseClassName) throws Exception {
              Class clazz = null;
              String qualifiedClassName = className.replaceAll("/", ".");
              try {
              clazz = Thread.currentThread().getContextClassLoader().loadClass(
              qualifiedClassName);

              } catch (Exception e) {
              Class c = Class.forName("java.lang.ClassLoader");
              Class[] args = new Class[] { String.class, byte[].class, int.class,
              int.class };
              java.lang.reflect.Method method = c.getDeclaredMethod(
              "defineClass", args);
              Object[] params = new Object[] { qualifiedClassName,
              writer.toByteArray(), new Integer(0),
              new Integer(writer.toByteArray().length) };
              ClassLoader loader = Thread.currentThread().getContextClassLoader();
              method.setAccessible(true);
              clazz = (Class) method.invoke(loader, params);

              method = c.getDeclaredMethod("resolveClass",
              new Class[] { Class.class });
              method.setAccessible(true);
              method.invoke(loader, new Object[] { clazz });

              }
              return clazz;
              }

              • 4. Re: No ClassLoaders found for: ClassLoading problem in JMS M
                Adrian Brock Master

                 

                "avis1977" wrote:
                Thats correct... we are infact using the defineClass()

                That's not surprising since there is no other way to load a class.
                Is there a way still to make this class available to the RepositotyClass loader.


                Yes. As long as you haven't already tried to load the class,
                otherwise it will cache the miss and tell you forever the class could not be
                loaded.


                By the way the classLoader instance that I get at the point of time when I generate my code is an instance of the GenericClassLoader.


                That's not a JBoss classloader of any type. I can't even tell you whose it is
                since you don't include the package name.

                The other information doesn't make your question any more answerable than it was originally.
                It's just some debug code for which you don't show any output or where
                it is being executed.

                Let me make some observations (I'm leaving this thread now).

                1) THIS IS NOT A QUESTION ABOUT JMS - wrong forum

                2) If you are going to play with classloaders then you need to understand how
                they work.
                In particular the JBoss classloading structure, i.e. what is visible from what context
                e.g. each ejb gets its own thread context classloader (even if they share
                the same underlying parent classloader)

                3) What you are doing won't even work if you enable the java security manager.

                4) If you really want your question answered (when you post it in a forum
                that is relevant) then you need to post pertinent information.

                e.g. I've yet to see the code that actually defines the class, where that is done
                against which classloader, etc.

                When I say which classloader, I mean classloader.toString() and
                a print of the classloader.getParent() stack, NOT some code doing
                Thread.currentThread.getContextClassLoader()
                

                which it meaningless since it could have any value depending upon where your code executes.

                The list of what is required for somebody to understand your question
                is longer than this, you can find it on the WIKI.
                I'm certainly not going to go through 20 posts to try to squeeze that information out of you.

                • 5. Re: No ClassLoaders found for: ClassLoading problem in JMS M
                  prat Bhat Newbie

                  I am also facing the same problem.

                  Hey avis , you got the solution??
                  Please share with us..


                  Thanks,
                  Prat