Announcement Announcement Module
Collapse
No announcement yet.
problem when proxy class using CGLIB Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • problem when proxy class using CGLIB

    I'm trying to play with 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:
    Code:
       <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>
    Questions:
    1. I used the cglib-nodep-2.1_2.jar, but I see there is some other jar files like cglib-2.1_2.jar on sourceforge, what's the difference? Am I using the correct one?
    2. Is there any doc on the web explaing how to use the CGLIB?

    Thanks in advance.

  • #2
    The answer your last questions first - you are using the correct JAR file, the only different being the way in which the ASM dependency is packaged. There is very little documentation on how to use CGLIB, although a quick google will throw up a few articles.

    Are you certain that the fields of the *target* object are getting nulled and not of the *proxy*?

    Rob

    Comment


    • #3
      Thanks for your response!

      My "target" class is a Spring MVC controller class, and when I run in debugging mode(MyEclipse, WebLogic8.1), I can see that the "this" variable(i.e. myTestController) is showing as "com.xxx.yyy$$EnhancedByCGLIB$$cb575b0d". So I guess I'm looking at the "proxy" object ( it has fiedls like "CGLIB$CALLBACK_0" ...)

      Also, when I started my WebLogic server in MyEclipse, I got several warnings saying "Unable to install breakpoint in com.xxx.yyy$$EnhancedByCGLIB$$ce1308: due to missing line number attributes. Modify compiler options to generate line number attributes" . I did put break points in Spring's DebugInterceptor, but the strange part is that, during the applicationContext init phase, the break points did get reached:
      Thread[main]...
      --DebugInteceptor(AbstractTraceInteceptor).invoke() line:76
      --Cglib2AopProxy$CglibMethodInvocation().proceed() line:144
      --Cglib2AopProxy$DynamicAdvisedInterceptor.intercept (Obj, Method, Obj[], methodProxy) line:606
      --com.xxx.yyy$$EnhancedByCGLIB$$cb575b0d.toString(0 line: not available
      --String.valueOf()
      --StringBuffer.append()
      --SimpleUrlHandlerMapping().registerHandler() line:190
      --SimpleUrlHandlerMapping.initApplicationContext() line: 96
      ....

      while after the app is started, those breakpoints were never reached anymore.

      Since the proxies are created dynamically during runtime, i assume there is no need to include spring_aop.jar and cglib-nodep-2.1_2.jar in the compile class path, they are only needed in the final WAR file. But even when I include those in the compile class path, it doesn't make any difference.

      Comment


      • #4
        You will need Spring AOP jar on the classpath for compilation. There should be no reason whey you can't place breakpoints inside your interceptors. Certainly, it works for me when I try it.

        Rob

        Comment


        • #5
          Right now, I do have the Spring AOP jar on my classpath for compilation.

          Any idea why I have all the null instance fields in the "proxy" ojbect?

          Comment


          • #6
            I've got the same problem. I try to add an interceptor to my form controller, and all properties injected into form controller (my services needed by form controller) are null in proxied object. I've added some logging messages to constructor and setters of controller, and I realised that when spring try to add advice and create proxy with CGLIB only constructor of target bean is invoked.

            Comment


            • #7
              The fields should be null in the proxy - all method calls are eventually directed to the target object so the field values from the target are used.

              Rob

              Comment


              • #8
                Originally posted by robh
                The fields should be null in the proxy - all method calls are eventually directed to the target object so the field values from the target are used.
                But they aren't
                Here is my simple example:
                Code:
                	<bean id="autoryzacjaEdycjiAdvice"
                		class="pl.eltel.sem.web.security.AutoryzacjaEdycjiAdvice">
                		<property name="pozycjeService" ref="pozycjeService" />
                		<property name="usterkiService" ref="usterkiService" />
                		<property name="uzytkownicyService" ref="uzytkownicyService" />
                		<property name="zmianyService" ref="zmianyService" />
                	</bean>
                
                	<bean id="autoryzacjaEdycjiAdvisor"
                		class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
                		<property name="mappedNames">
                			<list>
                				<value>onSubmit</value>
                			</list>
                		</property>
                		<property name="advice" ref="autoryzacjaEdycjiAdvice" />
                	</bean>
                         <!--- ...  -->
                       <bean id="edytujPozycjeController" class="org.springframework.aop.framework.ProxyFactoryBean">
                		<property name="interceptorNames">
                		       <list>
                		              <value>autoryzacjaEdycjiAdvisor</value>
                		       </list>
                		</property>
                		<property name="target">
                		       <bean class="pl.eltel.sem.web.controller.EdytujPozycjeFormController" singleton="true">
                		
                		              <property name="kategorieService">
                		                     <ref bean="kategorieService" />
                		              </property>
                		
                		              <property name="pozycjeService" ref="pozycjeService" />
                		
                		              <property name="uzytkownicyService" ref="uzytkownicyService" />
                		
                		              <property name="formView">
                		                     <value>edytujPozycje</value>
                		              </property>
                		              <property name="successView">
                                                     <value>changesSaved</value>
                		              </property>
                		              <property name="validator">
                		                     <bean class="pl.eltel.sem.web.validator.PozycjaValidator"></bean>
                		              </property>
                		       </bean>
                		</property>
                	</bean>
                And here is my formBackingObject method in pl.eltel.sem.web.controller.EdytujPozycjeFormContr oller:
                Code:
                	protected Object formBackingObject&#40;HttpServletRequest request&#41;
                            throws ServletException &#123;
                    			return  pozycjeService.get&#40;request.getParameter&#40;"id"&#41;&#41;;
                       &#125;
                The NPE is thrown, because pozycjeService is null. What's wrong ?

                Comment


                • #9
                  Rob,

                  I have the same problem for Null Pointer Exception:

                  Code:
                   <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
                  Code:
                  protected ModelAndView handle&#40;HttpServletRequest request,
                  			HttpServletResponse response, Object command,
                  			BindException errors&#41; throws Exception
                  is invoked on myTestController, it calles:
                  Code:
                  someDelegate.doSth&#40;&#41;
                  but because "someDelegate" is NULL, the app failed with NPE.

                  Comment


                  • #10
                    Can you post an issue for this, preferably with a tese case, on to JIRA. I'll get it running in the debugger and see what the problem is.

                    Rob

                    Comment


                    • #11
                      F.Y.I

                      http://opensource.atlassian.com/projects/spring/browse/SPR-1211[/url]

                      Comment


                      • #12
                        Hi,

                        I'm trying to do the same sort of thing. I understand that the final methods in the SimpleFormController (in my case) don't get proxied and that's why dependency injection is failing. Has anyone found a solution for this? I really need to proxy SimpleFormController and as it doesn't descend from some common FormController interface I can't use JDK proxies to get around this.

                        Any thoughts greatly appreciated.

                        Comment


                        • #13
                          I have the same problem ... Has anyone found a solution ? Is it just impossible to proxy a SimpleFormController ?

                          Comment


                          • #14
                            Was this issue ever solved?

                            Was this issue ever solved?

                            It sounds just like my problem using @AspectJ advice than run without problem using dynamic proxies, but won't trigger when switching to CGLIB:
                            http://forum.springframework.org/sho...ighlight=cglib

                            Comment

                            Working...
                            X