Stripes

StripesRuntimeException thrown in AnnotatedClassActionResolver when overriding handler but returning a subclass of the original method

Details

Description

A net.sourceforge.stripes.exception.StripesRuntimeException is thrown in error at:

net.sourceforge.stripes.controller.AnnotatedClassActionResolver.processMethods(AnnotatedClassActionResolver.java:226)

The exception message is "The ActionBean class <classname? declares multiple event handlers for event '<eventname>'"

This occurs when processing methods for an actionBean that overrides a super class handler with a method returning a subclass of the original method (eg RedirectResolution overriding Resolution). The reason for the error is that AnnotatedClassActionResolver.processMethods is not expecting class.getDeclaredMethods() to include bridge methods. I will attach a test case that displays the problem.

Workaround is to refactor subclasses to return Resolution rather than ForwardResolution, RedirectResolution etc but it's valid in Java to override methods this way so it should be supported ideally.

The solution is to change AnnotatedClassActionResolver.java, line 220 as follows:

if ( Modifier.isPublic(method.getModifiers()) && !method.isBridge() ) {

Activity

Hide
Paul White added a comment - 02/Jul/09 4:28 AM

This test case demonstrates the issue. It passes when the above change to AnnotatedClassActionResolver.java is made.

Show
Paul White added a comment - 02/Jul/09 4:28 AM This test case demonstrates the issue. It passes when the above change to AnnotatedClassActionResolver.java is made.
Hide
Frederic Daoud added a comment - 26/Sep/09 8:15 PM

Hi Paul,

I understand the issue and that the fix is simple, and it's great that you also included a test to exercise the problem and solution. I'm just curious though: can you explain why you need to return e.g. ForwardResolution instead of just Resolution from your event handler method? Event handler methods are used by Stripes; and even if you use them directly as well, ideally you'd work with the interface, not with a specific implementation.

Let me know what you think.

Thanks,
Freddy

Show
Frederic Daoud added a comment - 26/Sep/09 8:15 PM Hi Paul, I understand the issue and that the fix is simple, and it's great that you also included a test to exercise the problem and solution. I'm just curious though: can you explain why you need to return e.g. ForwardResolution instead of just Resolution from your event handler method? Event handler methods are used by Stripes; and even if you use them directly as well, ideally you'd work with the interface, not with a specific implementation. Let me know what you think. Thanks, Freddy
Hide
Paul White added a comment - 27/Sep/09 5:02 AM

Hi Freddy,

I don't think there's a absolute need to subclass Resolution on return types but covariance is a principle that I think provides some tidy design options in Java 1.5

I like the idea of being able to override a default handler and change the return type to a RedirectResolution, forcing subsequent subclasses to redirect on the same action.

Also, it seems reasonable to need to use handlers directly in applications. It might be useful to know you are getting a specific Resolution subclass as some of them offer different methods to others. Covariance avoids the need for casting and helps guaruntee type safety at compile time.

In summary, these issues can be worked around. However, anyone using covariant return types on Resolution methods will get the above error which doesn't offer much help in diagnosing the root of the problem. It took a fair amount of debugging for me to track it down.

-Paul

Show
Paul White added a comment - 27/Sep/09 5:02 AM Hi Freddy, I don't think there's a absolute need to subclass Resolution on return types but covariance is a principle that I think provides some tidy design options in Java 1.5 I like the idea of being able to override a default handler and change the return type to a RedirectResolution, forcing subsequent subclasses to redirect on the same action. Also, it seems reasonable to need to use handlers directly in applications. It might be useful to know you are getting a specific Resolution subclass as some of them offer different methods to others. Covariance avoids the need for casting and helps guaruntee type safety at compile time. In summary, these issues can be worked around. However, anyone using covariant return types on Resolution methods will get the above error which doesn't offer much help in diagnosing the root of the problem. It took a fair amount of debugging for me to track it down. -Paul
Hide
Frederic Daoud added a comment - 27/Sep/09 6:30 AM

Thanks for the clarification Paul.
I've added your test case and the fix in revision 1152.

Show
Frederic Daoud added a comment - 27/Sep/09 6:30 AM Thanks for the clarification Paul. I've added your test case and the fix in revision 1152.

People

Vote (0)
Watch (0)

Dates

  • Created:
    02/Jul/09 4:27 AM
    Updated:
    04/Jan/11 1:26 PM
    Resolved:
    27/Oct/09 1:57 PM