3 Replies Latest reply on Nov 26, 2009 12:19 AM by marius.bogoevici

    ClassLoader inside deloyed bean cannot find existing class

    ivanyuan

      Hi Guru,

      With the help from spring integration community, I can successfully deploy spring beans using deployer release 2.5 (jdk5) in JBoss 4.2.2GA and I can also access the deployed beans from another web application.

      However I am running into a problem of using ClassLoader inside the deployed spring beans.

      From my web application, I can get bean reference called "billingBean". However when I invoke one method of this bean, which will dynamically create some instances using classloader, I got "java.lang.ClassNotFoundException", and the stacktrace is as below:

      2009-Nov-23 14:53:17] ERROR - java.lang.ClassNotFoundException: com.iseemedia.provisioningbilling.actionflow.action.AddSubscriptionAction
      
      [2009-Nov-23 14:53:17] ERROR - at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
      
      [2009-Nov-23 14:53:17] ERROR - at java.security.AccessController.doPrivileged(Native Method)
      
      [2009-Nov-23 14:53:17] ERROR - at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
      
      [2009-Nov-23 14:53:17] ERROR - at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
      
      [2009-Nov-23 14:53:17] ERROR - at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
      
      [2009-Nov-23 14:53:17] ERROR - at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
      
      [2009-Nov-23 14:53:17] ERROR - at com.iseemedia.provisioningbilling.actionflow.ActionFlow.buildFlow(ActionFlow.java:49)
      
      [2009-Nov-23 14:53:17] ERROR - at com.iseemedia.provisioningbilling.actionflow.ActionFlow.<init>(ActionFlow.java:26)
      
      [2009-Nov-23 14:53:17] ERROR - at com.iseemedia.provisioningbilling.actionflow.ActionFlowFactory.getActionFlow(ActionFlowFactory.java:49)
      
      [2009-Nov-23 14:53:17] ERROR - at com.iseemedia.provisioningbilling.session.SessionManagement.createSession(SessionManagement.java:173)
      
      [2009-Nov-23 14:53:17] ERROR - at com.iseemedia.provisioningbilling.impl.ProvisioningBillingImpl.asyncSubscribe(ProvisioningBillingImpl.java:219)
      
      [2009-Nov-23 14:53:17] ERROR - at com.iseemedia.provisioningbilling.intf.ServiceBillingAdapter.subscribe(ServiceBillingAdapter.java:171)
      
      [2009-Nov-23 14:53:17] ERROR - at com.iseemedia.subscription.common.WebServiceBillingAdapter.subscribeRequest(WebServiceBillingAdapter.java:47)
      
      [2009-Nov-23 14:53:17] ERROR - at com.iseemedia.subscription.webservice.SubscriptionWS.manageSubscription(SubscriptionWS.java:108)
      
      [2009-Nov-23 14:53:17] ERROR - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      
      [2009-Nov-23 14:53:17] ERROR - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      
      [2009-Nov-23 14:53:17] ERROR - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      
      [2009-Nov-23 14:53:17] ERROR - at java.lang.reflect.Method.invoke(Method.java:585)
      
      [2009-Nov-23 14:53:17] ERROR - at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:166)
      
      [2009-Nov-23 14:53:17] ERROR - at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:82)
      
      [2009-Nov-23 14:53:17] ERROR - at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:122)
      
      [2009-Nov-23 14:53:17] ERROR - at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:70)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
      
      [2009-Nov-23 14:53:18] ERROR - at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:417)
      
      [2009-Nov-23 14:53:18] ERROR - at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
      
      [2009-Nov-23 14:53:18] ERROR - at java.util.concurrent.FutureTask.run(FutureTask.java:123)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:98)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:104)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:99)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:352)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:144)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:163)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.cxf.transport.servlet.AbstractCXFServlet.doGet(AbstractCXFServlet.java:145)
      
      [2009-Nov-23 14:53:18] ERROR - at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
      
      [2009-Nov-23 14:53:18] ERROR - at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      
      [2009-Nov-23 14:53:18] ERROR - at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
      
      [2009-Nov-23 14:53:18] ERROR - at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
      
      [2009-Nov-23 14:53:18] ERROR - at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      
      [2009-Nov-23 14:53:18] ERROR - at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
      
      [2009-Nov-23 14:53:18] ERROR - at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
      
      [2009-Nov-23 14:53:18] ERROR - at java.lang.Thread.run(Thread.java:595)
      
      


      The not-found-class, com.iseemedia.provisioningbilling.actionflow.action.AddSubscriptionAction actually is inside the spring archive file. I also tried to copy the spring archive file to default/lib (of course, I renamed it as *.jar), I still got same exception.

      Here is the snapshot of my code that will dynamically create some instances. This piece of code worked fine before using the spring deployer.

       HashMap<String, Action> aMap = new HashMap<String, Action>();
       for (String key : flowDef.getActionMap().keySet())
       {
       ActionDef aDef = flowDef.getActionMap().get(key);
      
       Action a = (Action)ClassLoader.getSystemClassLoader().loadClass(aDef.getType()).newInstance();
       aMap.put(key, a);
       }
      


      The bold line is the actual cause of the exception. I just wonder which class loader I should use inside a deployed bean?

      Thanks in advance,

      Ivan Yuan

        • 1. Re: ClassLoader inside deloyed bean cannot find existing cla
          marius.bogoevici

          Hmm ... have you tried with the TCCL (thread-context classloader)?

          • 2. Re: ClassLoader inside deloyed bean cannot find existing cla
            ivanyuan

            Hi Marius,

            Thanks for your help again.

            I didn't try TCCL, but I guess, in my scenario, the invocation is from web application, the system class loader and thread-context class loader are all related to web application (not the spring deployer).

            As such I did the following trick to make it work, I implemented BeanClassLoaderAware interface in the class where I need class loader. Whenever I need class loader, I just use this one, it works perfect for me.

            In this way, the class loader will be invoked and set when the bean is deployed, i.e., the class loader is same as the class loader of the spring deployer. This trick does the job!

            I have another question about how to access a deployed spring bean from other spring context which is managed by MULE. I think, better to ask you in different thread.


            Thank you so much,

            Ivan Yuan

            • 3. Re: ClassLoader inside deloyed bean cannot find existing cla
              marius.bogoevici

              Yes, that makes sense. To the extent that the class names are injected via Spring, you can take advantage of the fact that Spring's PropertyEditor knows how to convert a String value to a Class and can inject them directly.