5 Replies Latest reply on Feb 8, 2010 1:16 PM by micjohnson997

    Calling EJB from servlet - EJB's interface class not found

    micjohnson997

      I have deployed several EJBs into an EAR on JBoss 6.0.0 M1.  I then have a separate WAR (not deployed inside the EAR) with a servlet that uses InitialContext.lookup() on the remote name of the EJB.  When doing this, I get a ClassNotFoundException for the interface class, even though the interface class is inside a JAR in the WAR's WEB-INF/lib directory. Here's the start of the stack trace:

       

      javax.naming.NamingException: Could not dereference object [Root exception is java.lang.RuntimeException: Can not find interface declared by Proxy in our CL + org.jboss.web.tomcat.service.WebCtxLoader$ENCLoader@efdd6a]
           at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure(NamingContext.java:1508)
           at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:824)
           at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688)
           at javax.naming.InitialContext.lookup(InitialContext.java:392)

       

      then of course there's a bunch more stuff, followed by:

       

      Caused by: java.lang.ClassNotFoundException: <My interface class name>
           at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
           at java.security.AccessController.doPrivileged(Native Method)
           at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
           at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
           at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
           at java.lang.Class.forName0(Native Method)
           at java.lang.Class.forName(Class.java:247)
           at org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory.redefineProxyInTcl(ProxyObjectFactory.java:406)

       

      I've seen several posts talking about potential classloader issues, but I'm not familiar with the JBoss class loading scheme, so I was hoping someone had written up some good directions on how to correctly configure everything for calling an EJB from a WAR.

       

      Thanks in advance,

      Mike Johnson

        • 1. Re: Calling EJB from servlet - EJB's interface class not found
          jaikiran

          micjohnson997 wrote:

           

          When doing this, I get a ClassNotFoundException for the interface class, even though the interface class is inside a JAR in the WAR's WEB-INF/lib directory. Here's the start of the stack trace:

          If you have the bean interfaces in the .war/WEB-INF/lib/somejar.jar, then i would have expected this to work - atleast not throw a ClassNotFoundException. Can you post the output of:

           

          jar -tf somejar.jar
          

           

          where somejar.jar is the one which is placed in .war/WEB-INF/lib and contains the bean interfaces.

           

          As for the details around JBoss classloading, see these wiki pages:

           

          http://community.jboss.org/wiki/ClassLoadingConfiguration

          http://community.jboss.org/wiki/JBossClassLoadingUseCases

          • 2. Re: Calling EJB from servlet - EJB's interface class not found
            micjohnson997

            The .class file for the interface is present in the JAR.  In addition, I added another line prior to my ctx.lookup() call that says:

             

            System.out.println(MyInterfaceClass.class.toString());

             

            And I get good output from that, which tells me that the interface class is being found in the classpath.  So I guess I'm confused as to what the call in InitialNamingContext uses as its classpath?

            • 3. Re: Calling EJB from servlet - EJB's interface class not found
              jaikiran

              Mike,

               

              If you have a sample application which easily reproduces this, then please create a JIRA here https://jira.jboss.org/jira/browse/EJBTHREE and attach the application to that JIRA. We'll take a look.

              • 4. Re: Calling EJB from servlet - EJB's interface class not found
                micjohnson997

                Sorry it took me a while to get back to this -- I have been out of town. OK, the short answer is, this isn't a problem anymore; the piece of info I neglected to provide, and which at the time didn't seem pertinent but in hindsight is very pertinent, is that this WAR I have been deploying is a Liferay portlet WAR, and I have been deploying it via Liferay, which is supposed to then deploy it to JBoss.  Apparently something is going wonky in the Liferay deployment step.  Just by accident, I deployed the WAR directly into JBoss (skipping Liferay), and then ran my test app -- and voila, my calls to the EJBs from the servlet in the WAR succeeded!  So we are now trying to track down what could be getting messed up with the Liferay 5.2.x -> JBoss 6.0.0 M1 deployment.  We can see that Liferay is significantly changing the web.xml descriptor, which might have something to do with it. We can also see that all of the files that are needed (including the JAR containing the interface classes) are deployed correctly. I don't see anything that specifically talks about a classpath in the modified web.xml file, but we're early in our investigations.  I will report back if we find anything -- we can't be the only people trying to use Liferay 5.2.x with JBoss 6.0.0 M1...

                • 5. Re: Calling EJB from servlet - EJB's interface class not found
                  micjohnson997

                  If anyone else encounters this, here's the deal -- Liferay's "speed filters" (which minify and compress output) plays havoc somehow with the classpath, so the servlets in our portlet WAR (which made calls to EJBs) did not have the correct classpath.  We haven't gone too in-depth to figure out how to really fix this so that the speed filters are still present, but to work around this, we just disabled the filters by adding the following line into the liferay-plugin-package.properties file:

                   

                  {code}speed-filters-enabled=false{code}

                   

                  Once the filters are disabled, everything works as expected.