Results 1 to 7 of 7

Thread: Cache proxy and Unit test

  1. #1
    Join Date
    May 2007
    Posts
    3

    Default 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. #2
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    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

  3. #3
    Join Date
    May 2007
    Posts
    3

    Default

    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?

  4. #4
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    Quote 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.

    Quote 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

  5. #5
    Join Date
    May 2007
    Posts
    3

    Default

    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.

  6. #6
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    Quote 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

  7. #7

    Default 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 at 01:56 AM. Reason: Title editing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •