Announcement Announcement Module
Collapse

Spring Modules forum decommissioned in favor of Spring Extensions

As the Spring Modules project has been replaced by the Spring Extensions (http://www.springsource.org/extensions) project, this forum has been decommissioned in favour of Spring Extensions one at:
http://forum.springsource.org/forumdisplay.php?f=44

Please see the Spring Extensions home page for a complete list of current projects in Java, .NET and ActionScript. You can also propose one if you want.

Cheers,
Costin Leau
SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
http://twitter.com/costinl
See more
See less
Cache proxy and Unit test Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cache proxy and Unit test

    My unit tests start failing after adding declarative caching in applicationContext.xml. This is due to I can no longer retrieve a bean assuming its type, when it's being proxied dynamically.

    E.g. to get a service whose get* methods are declared to be cached,

    ProductService svc = (ProductService)application.getBean("ProductServic e)

    is now failing with,

    java.lang.ClassCastException: $Proxy6


    Does anyone know how to get the wrapped bean out of a Proxy? I prefer not having to run tests using a "test" version of applicationContext if I can help it.

    Thanks
    James

  • #2
    Is ProductService a class or an interface type? I guess it is a class implementing interfaces, because in that case the proxy does implement all interfaces but does not extend the class itself.

    So either program against interfaces or force the proxy generation to use subclassing by setting the "proxy-target-class" attribute to "true".

    Regards,
    Andreas

    Comment


    • #3
      Thanks for the reply Andreas.

      Yes ProoductService is a impl class and the proxy did implement the methods of interfaces.

      Since I'm testing methods other than those specified in the interface, I can't cast the bean to the interface type - thus can't program against the interface in this case.

      I'm using BeanNameAutoProxyCreator to specify beanNames and interceptorNames. Where can I add the "proxy-target-class" attribute?

      BTW, is there any penalty using subclass proxies?

      Comment


      • #4
        Originally posted by dancnfoo View Post
        I'm using BeanNameAutoProxyCreator to specify beanNames and interceptorNames. Where can I add the "proxy-target-class" attribute?
        Setting the "shouldProxyTargetClass" property of the BeanNameAutoProxyCreator to "true" should do the trick.

        Originally posted by dancnfoo View Post
        BTW, is there any penalty using subclass proxies?
        No there isn't. There are only some restrictions (e.g. concerning final methods).

        Regards,
        Andreas

        Comment


        • #5
          After adding the proxyTargetClass property, downloading CGLIB, ASM jars, and adding no-arg constructor to the impl class and its superclasses, the unit tests are finally passing.

          In the end however, I didn't go for this approach. It feels unnatural to force the use of CGLIB and making non-biz related code changes just to support proxy subclassing.

          After digging around I discover dynamic proxies implement Advised, where underlying bean can be retrieved by,
          ((Advised)proxiedBean)getTargetSource().getTarget( )

          Knowing this code ties Spring AOP to the code, it's good enough in my case as the code stays in unit tests.

          I imagine this is a common issue whenever AOP is applied, especially obvious in unit tests. A generated proxy has to be a subclass of the proxied object in order to casted to fully test all the methods. Is forcing the use of CGLIB a generic solution? Spring docs recommends using JDK proxy whenever possible. This constraint sounds to me I always have to use CGLIB.

          Comment


          • #6
            Originally posted by dancnfoo View Post
            Is forcing the use of CGLIB a generic solution? Spring docs recommends using JDK proxy whenever possible. This constraint sounds to me I always have to use CGLIB.
            You just have to use cglib when you deal directly with classes and not with interfaces. As it is recommended to program against interfaces you should be able to use java dynamic proxies in these cases.

            Regards,
            Andreas

            Comment


            • #7
              DATA not CACHED .data file having 0KB in size

              Hi,
              i'm using springmodules3.0+EHCacHE.

              i found Mycache.data has got generated with 0KB in size when i call proxyBean. I think it means data is not getting cached.

              Pls see the Spring's context.xml file.

              <bean id="proxyBean"
              class="org.springmodules.cache.interceptor.proxy.C acheProxyFactoryBean">
              <property name="cacheProviderFacade" ref="cacheProviderFacade" />
              <property name="cachingModels">
              <map>
              <entry key="get*">
              <bean
              class="org.springmodules.cache.provider.ehcache.Eh CacheCachingModel">
              <property name="cacheName"
              value="CITeCOMMERCEPORTAL_CACHE" />
              </bean>
              </entry>
              </map>
              </property>
              <property name="flushingModels">
              <map>
              <entry key="update*">
              <bean
              class="org.springmodules.cache.provider.ehcache.Eh CacheFlushingModel">
              <property name="cacheNames">
              <list>
              <value>CITeCOMMERCEPORTAL_CACHE</value>
              </list>
              </property>
              </bean>
              </entry>
              </map>
              </property>
              <property name="target" ref="securityServiceAdaptor" />
              </bean>

              I'm calling proxyBean as follows:

              securityServiceAdaptor = (SecurityServiceAdaptor)factory.getBean("proxyBean ");

              Here, SecurityServiceAdaptor is an interface.

              When i invoke this is the message i'm getting on console without any errors:

              Sep 4, 2007 12:06:40 PM org.springframework.beans.factory.xml.XmlBeanDefin itionReader loadBeanDefinitions
              INFO: Loading XML bean definitions from class path resource [beans4cache.xml]
              Sep 4, 2007 12:06:41 PM org.springframework.cache.ehcache.EhCacheManagerFa ctoryBean afterPropertiesSet
              INFO: Initializing EHCache CacheManager

              Could anybody throw your light on this.

              Thanks in advance,
              Ganesh
              Last edited by ganeshgadi; Sep 4th, 2007, 02:56 AM. Reason: Title editing

              Comment

              Working...
              X