Description
William Ashley opened SPR-5959 and commented
Here is a condensed example of the problem I'm encountering:
Controller:
package com.test;
import java.io.PrintWriter;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@Transactional( readOnly=true )
public class Test
{
@ExceptionHandler
public void exception( Throwable t )
{
System.out.println( "In exception handler" );
}
@RequestMapping( "/" )
public void get()
{
throw new RuntimeException( "foo" );
}
}
Dispatcher servlet config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="com.test.MockTransactionManager"/>
<context:component-scan base-package="com.test"/>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
The exception handler is never invoked when the controller is proxied by CGLib (removing @Transactional
removes the proxy and restores the exception handler). A little digging led me to org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver where there is this iteration over methods of the controller
ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) {
method = ClassUtils.getMostSpecificMethod(method, handlerType);
[snip]
}
});
which does arrive eventually at the proper exception handler method of my controller class, but because of the call to ClassUtils.getMostSpecificMethod() it winds up back at the overridden method on the CGLib-generated class (which from what I noticed it had already visited). I haven't researched enough to say this is the problem though.
@RequestMapping
annotations appear to work normally through a proxied controller (and the @Transactional
annotation does function correctly), so I'm hoping this can be fixed.
Affects: 3.0 M3
Issue Links:
- MVC Annotation Inheritance [SPR-6093] #10761 MVC Annotation Inheritance ("duplicates")
- @ExceptionHandler doesn't work on CGLib-proxied controller in Portlet MVC [SPR-7337] #11996
@ExceptionHandler
doesn't work on CGLib-proxied controller in Portlet MVC
1 votes, 2 watchers