Issue 1:
Scott Frederick opened SPR-6693 and commented

Spring MVC @ExceptionHandler controller methods support a flexible argument list and return value, similiar to @RequestMapping-annotated methods. One option that is supported by @RequestMapping methods but not @ExceptionHandler methods is returning naked bean objects from the exception handler method.

For example, this type of exception handler method would be very convenient, especially when building RESTful services using a MarshallingView (the important detail is the "HelloResponse" return value from the handleBindException method):

@Controller
@RequestMapping("/Hello")
public class HelloController {
@RequestMapping(value = "/greet", method = RequestMethod.GET)
public HelloResponse greetGet(@Valid HelloRequest request) {
String message = "Hello, " + request.getTitle() + " " + request.getName();
return new HelloResponse(message);
}

@ExceptionHandler(BindException.class)
public HelloResponse handleBindException(BindException be) {
List<FieldError> errors = be.getFieldErrors();
HelloResponse response = new HelloResponse();
for (FieldError error : errors) {
response.addError(error.toString());
}
return response;
}
}

With a response object that looks like this:

@XmlRootElement(name = "response")
public class HelloResponse {
private String message;
private List<String> errors;
// getters and setters
}

Currently this code will throw an exception when the exception handler method returns to the framework:

java.lang.IllegalArgumentException: Invalid handler method return value: HelloResponse@caf0ed
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver.getModelAndView(AnnotationMethodHandlerExceptionResolver.java:353)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver.doResolveException(AnnotationMethodHandlerExceptionResolver.java:101)
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:109)
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1004)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:792)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

Affects: 3.0 GA

Attachments:

ExceptionHandler-return.patch (5.70 kB)

13 votes, 19 watchers

Issue 2:
Bob Tiernay opened SPR-9044 and commented

Problem

One common request I see quite frequently on the internet is the ability to have spring autowire a main class:

http://hvijay.wordpress.com/2011/07/02/spring-dependency-injection-in-applications-main-class/

http://forum.springsource.org/archive/index.php/t-47933.html

http://stackoverflow.com/questions/6820724/how-to-inject-properties-into-a-spring-bean-from-main-class

http://stackoverflow.com/questions/8313070/spring-bean-injection-in-main-method-class

http://stackoverflow.com/questions/3659720/spring-3-autowire-in-standalone-application

http://stackoverflow.com/questions/4787719/spring-console-application-configured-using-annotations

http://forum.springsource.org/showthread.php?75991-ContextConfiguration

There is no shortage of questions / solutions to this problem which illustrates a need for a standardized approach.

Solution

What I am proposing is combination of features between the following existing classes:

org.springframework.test.context.junit4.SpringJUnit4ClassRunner - provides functionality of the Spring TestContext Framework to standard JUnit 4.5+ tests

org.springframework.test.context.ContextConfiguration - class-level metadata that is used to determine how to load and configure an ApplicationContext for test classes

org.springframework.web.context.support.SpringBeanAutowiringSupport a convenient base class for self-autowiring classes that gets constructed within a Spring-based web application.

Thus provinding first class support for console based application context management and DI.

Features

Autowiring of main class dependencies

Auto-destruction of application context

Ability in the future to handle command line arguments as beans

Properties

Standardization

Consistency with other APIs

Minimal configuration

Intent revealing

Example

My visions is something like the following:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MainSupport;
import org.springframework.context.ContextConfiguration;
import org.springframework.context.support.AnnotationConfigContextLoader;

@ContextConfiguration(classes=AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class Main extends MainSupport {

@Autowired
private Service service;

public static void main( String[] args ) {
// MainSupport.execute
execute(args);
}

@Main
public void main() {
service.run();
}

}

The way this would work is as follows:

JVM calls main

main delegates to super class method MainSupport.execute provided by spring (analog of SpringBeanAutowiringSupport)

MainSupport.execute reads the @ContextConfiguration annotation and looks for a @Main annotation (analog of @Test)

MainSupport.execute creates the application context

MainSupport.execute create an application Main class instance

MainSupport.execute injects dependencies

MainSupport.execute wraps instance in a proxy that will advise the method annotated with @Main. This proxy will first call the annotated method and then destroy the application context

Issue Links:

#12732 Provide Java main() for launching Spring applications

4 votes, 10 watchers