Announcement Announcement Module
Collapse
No announcement yet.
SimpleRemoteStatelessSessionProxyFactoryBean - NoSuchMethodException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • SimpleRemoteStatelessSessionProxyFactoryBean - NoSuchMethodException

    Hi,

    When i try to use SimpleRemoteStatelessSessionProxyFactoryBean to access a Remote EJB that is deployed on the same server, I get NoSuchMethodExceptions when invoking methods on the returned proxy. (See stacktrace below)
    The problem only manifests itself when the component trying to access the EJB is deployed in an other EAR file than the EJB. If both are in the same EAR it works just fine. When I try to access an EJB that is deployed on another server it also works ok.

    We use Websphere Application Server 5.

    ApplicationContext.xml snippet:

    Code:
    	<bean id="loggingConsultFacade" class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
    		<property name="jndiName">
    			<value>ejb/x/y/z/ssdn/loggingconsultfacade/LoggingConsultFacadeHome</value>
    		</property>
    		<property name="businessInterface">
    			<value>x.y.z.ssdn.loggingconsultfacade.LoggingConsultFacade</value>
    		</property>
    		<property name="jndiEnvironment">
    			<props>
    				<prop key="java.naming.factory.initial">com.ibm.websphere.naming.WsnInitialContextFactory</prop>
    				<prop key="java.naming.provider.url">iiop://localhost:2809</prop>
    			</props>
    		</property>
    	</bean>
    Stacktrace:

    Code:
    java.lang.NoSuchMethodException: x.y.z.ssdn.loggingconsultfacade._LoggingConsultFacade_Stub.execute(x.y.z.ssdn.servicecommon.ServiceRequestContainer)
    		 at java.lang.Class.getMethod1(Class.java(Compiled Code))
    		 at java.lang.Class.getMethod(Class.java:1056)
    		 at org.springframework.remoting.rmi.RmiClientInterceptorUtils.doInvoke(RmiClientInterceptorUtils.java:102)
    		 at org.springframework.ejb.access.SimpleRemoteSlsbInvokerInterceptor.doInvoke(SimpleRemoteSlsbInvokerInterceptor.java:75)
    		 at org.springframework.ejb.access.AbstractRemoteSlsbInvokerInterceptor.invoke(AbstractRemoteSlsbInvokerInterceptor.java:114)
    		 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
    		 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
    		 at $Proxy1.execute(Unknown Source)
    		 at x.y.z.ssdn.common.webservice.XyzWebServiceEjbImpl.executeWebService(XyzWebServiceEjbImpl.java:86)
    		 at x.y.z.loggingconsult.web.backend.bcss.XyzLoggingConsultServiceImpl.send(XyzLoggingConsultServiceImpl.java:48)
    		 at x.y.z.loggingconsult.web.delegate.LoggingConsultDelegateImpl.findPersonData(LoggingConsultDelegateImpl.java:103)
    		 at x.y.z.loggingconsult.web.actions.FindPersonDataAction.executeAction(FindPersonDataAction.java:37)
    		 at x.y.z.loggingconsult.web.actions.LoggingConsultBaseAction.execute(LoggingConsultBaseAction.java:101)
    		 at org.springframework.web.struts.DelegatingActionProxy.execute(DelegatingActionProxy.java:105)
    		 at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
    		 at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
    		 at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
    		 at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)
    		 at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
    		 at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
    		 at com.ibm.ws.webcontainer.servlet.StrictServletInstance.doService(StrictServletInstance.java:110)
    		 at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet._service(StrictLifecycleServlet.java:174)
    		 at com.ibm.ws.webcontainer.servlet.IdleServletState.service(StrictLifecycleServlet.java:313)
    		 at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet.service(StrictLifecycleServlet.java:116)
    		 at com.ibm.ws.webcontainer.servlet.ServletInstance.service(ServletInstance.java:283)
    		 at com.ibm.ws.webcontainer.servlet.ValidServletReferenceState.dispatch(ValidServletReferenceState.java:42)
    		 at com.ibm.ws.webcontainer.servlet.ServletInstanceReference.dispatch(ServletInstanceReference.java:40)
    		 at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.handleWebAppDispatch(WebAppRequestDispatcher.java:983)
    		 at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:564)
    		 at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:200)
    		 at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java:119)
    		 at com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java:276)
    		 at com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java:71)
    		 at com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java:182)
    		 at com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java:334)
    		 at com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:56)
    		 at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:618)
    		 at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:443)
    		 at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:672)

  • #2
    From the working/ not working cases I would say it has something to do with classloading. However, I have no clue how that could happen.

    Does the failing scenario work, when you access the EJB the conventional way (i.e. without Spring)?

    Regards,
    Andreas

    Comment


    • #3
      Yes indeed, all works when I access the EJB's the conventional way.

      I even wrote my own EjbFactoryBean that works like the SimpleRemoteStatelessSessionFactoryBean. It also requires you to pass the parameters that are needed for lookup, looks up the EJB and returns it.

      But I'd rather use the SimpleRemoteStatelessSessionFactoryBean offcourse.

      Comment


      • #4
        What happens if you don't set the businessInterface property?

        Comment


        • #5
          "businessInterface" is a required property, it is checked for not being null in SimpleRemoteStatelessSessionProxyFactoryBean's afterPropertiesSet.

          Comment


          • #6
            Oh. Then set it to be the EJB's remote interface instead of the non-remote interface. I thought the business interface was inferred from JNDI lookup if businessInterface was not present. But since the JNDI name is the home, I guess that's not possible

            Comment


            • #7
              x.y.z.ssdn.loggingconsultfacade.LoggingConsultFaca de is the EJB Remote interface.

              Comment


              • #8
                I just saw that the method in question takes an argument of a user-defined type. Can you try to reproduce the scenario with a method that takes no arguments (or only arguments of simple Java types)?
                My point is that possibly the argument type could not be matched, because the argument's class might be loaded by different classloaders.

                Maybe you could try to log the classloader of both ServiceConsultFacade and ServiceRequestContainer classes in both of your EJBs and see if they differ.


                Regards,
                Andreas

                Comment


                • #9
                  Thanks for the tip Andreas.

                  I tried with a method that only takes and returns primitive types, and it worked. I allso figured out that the problem could be avoided on my developement pc by changing the classloader policy in wsad to "SINGLE" instead of "MULTIPLE". Causing all applications to use the same classloader.

                  A colleague pointed out that it probably has something to do with the IBM JVM, which optimizes bean calls to EJB's that run on the same server by circumventing serialization and calling the bean directly.

                  Comment


                  • #10
                    Good that you could get it running :-)
                    I agree with your colleague that the circumvention of serialization has an impact here, since the serialization process bridges the different classloaders. It's quite common for application servers to perform this kind of optimization. It has nothing to do with the underlying VM, though.

                    Regards,
                    Andreas

                    Comment

                    Working...
                    X