Issue Details (XML | Word | Printable)

Key: SPR-1211
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Rob Harrop
Reporter: Jieba Wu
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Spring Framework

problem when proxy class using CGLIB

Created: 08/Aug/05 10:48 AM   Updated: 17/Aug/05 08:15 AM
Component/s: SpringAOP
Affects Version/s: 1.2 final
Fix Version/s: 1.2.4

Time Tracking:
Not Specified

File Attachments: 1. Zip Archive cglib_test.zip (2 kB)

Image Attachments:

1. screenshot-Non-Controller.jpg
(71 kB)
Environment: Windows XP, WebLogic8.1


 Description  « Hide
I'm trying to use Spring AOP, so far it works fine when I proxy interfaces(i.e use JDK Dynamic proxy), but once I switched to proxy classes(i.e use CGLIB), all of the instance variable of the target classes become null during runtime.

Here is part of the app config:
------------------------------------------
<bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor"/>

<bean id="myTestController"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="myTestControllerTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>debugInterceptor</value>
</list>
</property>
</bean>

<bean id="myTestControllerTarget" class="com.xxx.yyy">
<property name="someDelegate"><ref bean="someDelegate"/></property>

<property name="viewName">
<value>testName</value>
</property>
</bean>
-----------------------
when the method

protected ModelAndView handle(HttpServletRequest request,
         HttpServletResponse response, Object command,
         BindException errors) throws Exception


is invoked on myTestController, it calles:

someDelegate.doSth()

but because "someDelegate" is NULL, the app failed with NPE.

 All   Comments   Work Log   Change History   FishEye   Builds      Sort Order: Ascending order - Click to sort in descending order
Rob Harrop added a comment - 08/Aug/05 01:02 PM
I added CglibProxyTests.testSPR1211() to try a reproduce this and I was unable to do so. Can you check to see if this test matches your scenario?

Jieba Wu added a comment - 08/Aug/05 01:35 PM
Somehow, the proxy works fine if the target class is not Spring MVC controller.
In this case, it's a stub controller(not implementing Spring's Controller interface).
You can see from the stack trace that "this" object is still the target class, the proxy class is TestController$$FastClassByCGLIB$...;
but if target class is Spring MVC controller, "this" object becomes RealController$$EnhancerByCGLIB$$...(not shown in this screen shot)

Rob Harrop added a comment - 09/Aug/05 05:05 AM
The screenshot you have shows the TestController object as being this. Can you check which version of CGLIB you are using? Older versions of CGLIB didn't support a feature that we can now use to prevent target object state from being reset in certain cases. You should use the version in the latest (1.2.3) Spring distribution.

If this doesn't work can you post your code for your TestController - I'll see if I can make this fail on may machine.

Jieba Wu added a comment - 09/Aug/05 12:46 PM
The testSPR1211() works fine for me too(I'm using the 2.1_2 verison for CGLIB). But when I run the test within application context, I can reproduce the NPE.

Rob Harrop added a comment - 10/Aug/05 05:34 AM
Can you create a test case that loads you actual application context and shows the NPE and post it here. I'm pretty much running blind at the moment until I can see this error actually manifested.

Rob

Jieba Wu added a comment - 10/Aug/05 08:00 AM
The attachement cglib_test.zip I put on yesterday contains the test case under app context, which you can reproduce the NPE.

Jieba Wu added a comment - 15/Aug/05 11:49 AM
Rob, are you able to reproduce the NPE from the file I posted earlier?

Jieba

Rob Harrop added a comment - 16/Aug/05 12:07 PM
Jieba,

I managed to get the test to fail finally. I know what the cause of this is now, but I'm not sure if there is an elegant way in which we can solve it. In the meantime, I would recommend that you use JDK proxies to get around this issue.

Rob

Rob Harrop added a comment - 17/Aug/05 01:47 AM
Jieba,

The final status of this issue is that you can't CGLIB to proxy the class you are trying to proxy. The reason for this is that the handleRequest() method is final and thus cannot be overridden by the proxy subclass.

I will be modifying the CGLIB proxy mechanism so that WARN messages are written in the log when there are methods on the class that are final.

Rob

Jieba Wu added a comment - 17/Aug/05 08:15 AM
Thanks, Rob.