Thursday, October 4, 2007

Spring dynamic proxy problem

I encountered a strange problem at work today: The following test code failed:

ServiceImpl service = applicationContext.getBean("serviceImpl");

The application context looks like this:

<bean id="serviceImpl" class="ServiceImpl"/>

ServiceImpl implements the Service interface.

Note that the reference type in the test code is ServiceImpl. I sometimes do this when I need to test drive methods that are not in the implemented interface.

The error was a ClassCastException, which made no sense. Looking at the error, it said that it was unable to cast Proxy-yadayada to ServiceImpl.

It turns out that someone added some AOP stuff to the service classes. Spring then proxies the service implementation in one of two ways: if the class doesn't implement an interface it uses cglib to create a proxy.

But if the class does implement an interface Spring will interject a dynamic proxy which implements that interface between the original interface and implementation, and the above code will fail.

So what's the solution? The only immediate solution I see is to instantiate the service implementation yourself if you need to test drive methods that are not in the interface. Hardly ideal, but easy enough.

No comments: