Announcement Announcement Module
Collapse
No announcement yet.
aop:scoped-proxy, not retaining state, duplicate objects Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • aop:scoped-proxy, not retaining state, duplicate objects

    I'm converting an old EJB app using stateful session beans to use spring HttpInvoker. The trouble is, the session beans are not retaining state. Every time I call a method a brand new object is getting called.

    I have client code like this:

    Code:
    ApplicationContext ctx = new ClassPathXmlApplicationContext("client-beans.xml");
    spSession = (SpFinOtherSession)ctx.getBean("SpFinOtherSession");			
    spSession.create(serviceProviderId, password); // causes a new SpFinOtherSessionBean to be created on the server
    fundingCategories = spSession.getFundingCategories(); // causes a new SpFinOtherSessionBean to be created on the server
    You would think the last two lines would cause the same object on the server to be called, but no, each references a different object, and each causes a new object to be created on the server. Why? I need it to retain state.

    My httpInvoker-servlet.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
    	http://www.springframework.org/schem...ring-beans.xsd
    	http://www.springframework.org/schema/aop				
    	http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    	
    	<bean id="SpFinOtherSession" class="au.gov.ag.npc.financials.SpFinOtherSessionBean" scope="session">
    		<aop:scoped-proxy/>
    	</bean>
    	<bean name="/httpinvoker/SpFinOtherSession.http" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
    		<property name="service" ref="SpFinOtherSession"></property>
    		<property name="serviceInterface" value="au.gov.ag.npc.interfaces.SpFinOtherSession"></property>
    	</bean>
    </beans>
    client-beans.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    	
    	<bean id="SpFinOtherSession" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
    		<property name="serviceUrl" value="http://localhost:8080/httpinvoker/SpFinOtherSession.http"></property>
    		<property name="serviceInterface" value="au.gov.ag.npc.interfaces.SpFinOtherSession"></property>
    	</bean>
    </beans>
    Code:
    web.xml:
       	<servlet>
        	<servlet-name>httpInvoker</servlet-name>
        	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        	<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
        	<servlet-name>httpInvoker</servlet-name>
        	<url-pattern>*.http</url-pattern>
    	</servlet-mapping>
    Code:
    Debug stack trace when the contructor is called on the bean:
    			SpFinOtherSessionBean.<init>() line: 54	
    			NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method]	
    			NativeConstructorAccessorImpl.newInstance(Object[]) line: 57	
    			DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45	
    			Constructor<T>.newInstance(Object...) line: 525	
    			BeanUtils.instantiateClass(Constructor<T>, Object...) line: 148	
    			CglibSubclassingInstantiationStrategy(SimpleInstantiationStrategy).instantiate(RootBeanDefinition, String, BeanFactory) line: 89	
    			DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).instantiateBean(String, RootBeanDefinition) line: 1023	
    			DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBeanInstance(String, RootBeanDefinition, Object[]) line: 962	
    			DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 504	
    			DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 475	
    			AbstractBeanFactory$2.getObject() line: 338	
    			SessionScope(AbstractRequestAttributesScope).get(String, ObjectFactory) line: 44	
    			SessionScope.get(String, ObjectFactory) line: 93	
    			DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 333	
    			DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 195	
    			SimpleBeanTargetSource.getTarget() line: 35	
    			CglibAopProxy$DynamicAdvisedInterceptor.getTarget() line: 675	
    			CglibAopProxy$DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 626	
    			SpFinOtherSessionBean$$EnhancerByCGLIB$$f7b26b98.ejbCreate(BigDecimal, String, String) line: not available	
    			NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
    			NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57	
    			DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
    			Method.invoke(Object, Object...) line: 601	
    			AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) line: 317	
    			ReflectiveMethodInvocation.invokeJoinpoint() line: 190	
    			ReflectiveMethodInvocation.proceed() line: 157	
    			RemoteInvocationTraceInterceptor.invoke(MethodInvocation) line: 78	
    			ReflectiveMethodInvocation.proceed() line: 179	
    			JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 207	
    			$Proxy15.ejbCreate(BigDecimal, String, String) line: not available	
    			NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
    			NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57	
    			DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
    			Method.invoke(Object, Object...) line: 601	
    			RemoteInvocation.invoke(Object) line: 205	
    			DefaultRemoteInvocationExecutor.invoke(RemoteInvocation, Object) line: 39	
    			HttpInvokerServiceExporter(RemoteInvocationBasedExporter).invoke(RemoteInvocation, Object) line: 78	
    			HttpInvokerServiceExporter(RemoteInvocationBasedExporter).invokeAndCreateResult(RemoteInvocation, Object) line: 114	
    			HttpInvokerServiceExporter.handleRequest(HttpServletRequest, HttpServletResponse) line: 74	
    			HttpRequestHandlerAdapter.handle(HttpServletRequest, HttpServletResponse, Object) line: 51	
    			DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse) line: 925	
    			DispatcherServlet.doService(HttpServletRequest, HttpServletResponse) line: 856	
    			DispatcherServlet(FrameworkServlet).processRequest(HttpServletRequest, HttpServletResponse) line: 946	
    			DispatcherServlet(FrameworkServlet).doPost(HttpServletRequest, HttpServletResponse) line: 848
    Code:
    Stack trace when the method is called:
    		Daemon Thread [http-localhost/127.0.0.1:8080-1] (Suspended (breakpoint at line 139 in SpFinOtherSessionBean))	
    			SpFinOtherSessionBean.getFundingCategories() line: 139	
    			SpFinOtherSessionBean$$FastClassByCGLIB$$f5668edb.invoke(int, Object, Object[]) line: not available	
    			MethodProxy.invoke(Object, Object[]) line: 204	
    			CglibAopProxy$CglibMethodInvocation.invokeJoinpoint() line: 710	
    			CglibAopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() line: 157	
    			DelegatingIntroductionInterceptor.doProceed(MethodInvocation) line: 133	
    			DelegatingIntroductionInterceptor.invoke(MethodInvocation) line: 121	
    			CglibAopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() line: 179	
    			CglibAopProxy$DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 643	
    			SpFinOtherSessionBean$$EnhancerByCGLIB$$f7b26b98.getFundingCategories() line: not available [local variables unavailable]	
    			NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
    			NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57	
    			DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
    			Method.invoke(Object, Object...) line: 601	
    			AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) line: 317	
    			ReflectiveMethodInvocation.invokeJoinpoint() line: 190	
    			ReflectiveMethodInvocation.proceed() line: 157	
    			RemoteInvocationTraceInterceptor.invoke(MethodInvocation) line: 78	
    			ReflectiveMethodInvocation.proceed() line: 179	
    			JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 207	
    			$Proxy15.getFundingCategories() line: not available	
    			NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
    			NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57	
    			DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
    			Method.invoke(Object, Object...) line: 601	
    			RemoteInvocation.invoke(Object) line: 205	
    			DefaultRemoteInvocationExecutor.invoke(RemoteInvocation, Object) line: 39	
    			HttpInvokerServiceExporter(RemoteInvocationBasedExporter).invoke(RemoteInvocation, Object) line: 78	
    			HttpInvokerServiceExporter(RemoteInvocationBasedExporter).invokeAndCreateResult(RemoteInvocation, Object) line: 114	
    			HttpInvokerServiceExporter.handleRequest(HttpServletRequest, HttpServletResponse) line: 74	
    			HttpRequestHandlerAdapter.handle(HttpServletRequest, HttpServletResponse, Object) line: 51	
    			DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse) line: 925	
    			DispatcherServlet.doService(HttpServletRequest, HttpServletResponse) line: 856	
    			DispatcherServlet(FrameworkServlet).processRequest(HttpServletRequest, HttpServletResponse)
    Last edited by countach; Aug 27th, 2013, 08:33 AM. Reason: formatting

  • #2
    Please use [ code][/code ] tags when posting code, that way it remains readable, currently it isn't really readable.

    Code:
    ApplicationContext ctx = new ClassPathXmlApplicationContext("client-beans.xml");
    spSession = (SpFinOtherSession)ctx.getBean("SpFinOtherSession" );	 
    spSession.create(serviceProviderId, password); // causes a new SpFinOtherSessionBean to be created on the server
    fundingCategories = spSession.getFundingCategories(); // causes a new SpFinOtherSessionBean to be created on the server
    This code is wrong, you should NEVER (or at most ONCE) create an application context. Each time you do this you are recreating all the beans instead of reusing the existing once. Not to mention the fun problems you can run into with duplicate transaction managers, and shared resources.

    Also the http invoker is normally stateless so it doesn't retain any cookies or what so ever, so basically each request is going to result in a new session.

    Also you seem to try to mimick stateful session beans, why?! Wouldn't it be easier to not try to simulate stateful session beans?! If you want stateful session beans then do use stateful session beans.

    Instead of using the normal configuration let your client use the HttpComponentsHttpInvokerRequestExecutor instead of the default SimpleHttpInvokerRequestExecutor. This uses the more robust apache Http library which can be configured in better ways.

    Info here and here
    Last edited by Marten Deinum; Aug 27th, 2013, 03:40 AM.

    Comment

    Working...
    X