3

I am receiving a strange exception in my application's server log. The exception occurs when a GET request is being made to a certain URL. The URL has the following format -

/some_list/{id}/some_method

handler for which is defined like this -

@RestController
@Validated
public class SomeController {
    @Autowired
    private SomeService someService;

    @RequestMapping(value = "/some_list/{id}/some_method", method = RequestMethod.GET)
    public Collection<SomeObject> getCollection(
        @PathVariable @SomeCustomJavaxConstraintValidator String id,
        @RequestParam(required = true) 
            @SomeCustomJavaxConstraintValidator String someOtherID) {

        return someService.getSomething(id, someOtherID);
    }

    // other methods
}

The exception looks like this (message formatted to fit the question area) -

2016-03-13 14:46:09.956 ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - 
Failed to invoke @ExceptionHandler method: 
    public org.springframework.http.ResponseEntity<SomeEntity> 
        com.hogehoge.GenericExceptionHandler.handleServiceException(
            javax.servlet.http.HttpServletResponse, 
            com.hogehoge.CustomException)
java.lang.NullPointerException: Name is null
    at java.lang.Enum.valueOf(Enum.java:236) ~[na:1.8.0_66]
    at org.springframework.http.HttpMethod.valueOf(HttpMethod.java:27) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.http.server.ServletServerHttpRequest.getMethod(ServletServerHttpRequest.java:87) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:175) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:80) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:363) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:60) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:137) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:74) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1183) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1020) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [tomcat8-servlet-api-8.0.26.jar:na]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat8-servlet-api-8.0.26.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [tomcat8-catalina-8.0.26.jar:8.0.26]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat8-coyote-8.0.26.jar:8.0.26]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) [tomcat8-coyote-8.0.26.jar:8.0.26]
    at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1074) [tomcat8-coyote-8.0.26.jar:8.0.26]
    at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.run(Nio2Endpoint.java:1033) [tomcat8-coyote-8.0.26.jar:8.0.26]
    at org.apache.tomcat.util.net.Nio2Endpoint.processSocket0(Nio2Endpoint.java:594) [tomcat8-coyote-8.0.26.jar:8.0.26]
    at org.apache.tomcat.util.net.Nio2Endpoint.processSocket(Nio2Endpoint.java:578) [tomcat8-coyote-8.0.26.jar:8.0.26]
    at org.apache.tomcat.util.net.SecureNio2Channel$1.completed(SecureNio2Channel.java:86) [tomcat8-coyote-8.0.26.jar:8.0.26]
    at org.apache.tomcat.util.net.SecureNio2Channel$1.completed(SecureNio2Channel.java:79) [tomcat8-coyote-8.0.26.jar:8.0.26]
    at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126) [na:1.8.0_66]
    at sun.nio.ch.Invoker$2.run(Invoker.java:218) [na:1.8.0_66]
    at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) [na:1.8.0_66]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_66]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_66]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat8-util-8.0.26.jar:8.0.26]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_66]

GenericExceptionHandler is a @ControllerAdvice which is registered like this -

@ControllerAdvice
public class GenericExceptionHandler {
    // fields and others......

    @ResponseBody
    @ExceptionHandler(CustomException.class)
    public ResponseEntity<SomeEntity> handleServiceException(
        HttpServletResponse response, CustomException e) {

        // method implementation
    }

I could not reproduce this exception in my local environment as the exception apparently occurs at random. I tried to debug it following the stack trace, and it looks like for some reason the getMethod method of HttpServletRequest returns null (!!??), and as a result HttpMethod.valueOf is throwing this exception, but I don't know why this is the case.

Update

Although this is a Spring Boot app, it is being deployed on an independent tomcat server. The POM file has been configured with the maven plugin so that the repackaging is done properly. Also the packaging of the app has been marked as war. Sample -

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.hogehoge</groupId>
        <artifactId>some-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>some-app</artifactId>
    <packaging>war</packaging>

    <!-- Lots of other things -->

    <build>
        <finalName>the-mighty-app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- Some other plugins -->
        </plugins>
    </build>
</project>
2
  • 1
    Do you packaged a servlet-api library in your web app, which might be conflicting with the one from the container? Commented Mar 14, 2016 at 14:49
  • @thirstycrow: The app is being deployed on an independent tomcat container, and before that it is being repackaged by the spring boot maven plugin. Also there is no servlet-api jars included in the POM files. So I can safely assume that there is no duplicated servlet dependencies. Please see the update on the spring boot maven plugin configuration. Commented Mar 14, 2016 at 15:22

2 Answers 2

2

I checked latest Spring source code HttpEntityMethodProcessor.java(around line 175) and I see that code has changed slightly, now it is not possible to get NPE there. I see they switched back and forth a few times between: inputMessage.getMethod() == HttpMethod.GET and inputMessage.getMethod().equals(HttpMethod.GET)

Sign up to request clarification or add additional context in comments.

1 Comment

I will try to upgrade the Spring Boot version and see if the problem persists. Thanks for the insight, I think this might actually solve the problem.
2

In regards to your original question of Failed to invoke custom ExceptionHandler, That's probably because you have your ExceptionHandler only handling @ExceptionHandler(CustomException.class) while the exception that's actually thrown is NullPointerException. I normally also add a method (handler) for @ExceptionHandler(RuntimeException.class) in my ExceptionHandler so that I can handle runtime exceptions just like my custom exceptions.

In regards to where that nullpointer is coming from, as suggested above you could try and upgrade your Spring boot version, see if that fixes the issue.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.