Search code examples
grailsgrails-controllergrails-3.3

Grails 3.3.0 on Tomcat 7.0.57


We are trying to use response.outputStream in Grails 3.3.0 under Tomcat 7.0.57. However, when any bytes are written to the stream, we get this error:

org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/WriteListener

This seems to come from the 3.1 Servlet spec? But Tomcat 7 doesn't support 3.1, only 3.0. However, we've targeted the Grails app to the Tomcat version we are deploying to by doing this in dependencies:

provided "org.springframework.boot:spring-boot-starter-tomcat"

And this, later in the build.gradle file:

war {
   ext['tomcat.version'] = '7.0.57'
}

Anything else to try?


Solution

  • Turns out the problem was caused by Groovy introspection upon loading the class OnCommittedResponseWrapper, which has this:

        public void setWriteListener(WriteListener writeListener) {
            this.delegate.setWriteListener(writeListener);
        }
    

    Adding a @GrailsCompileStatic to the method(s) which use the response outputStream in ways like this:

    response.outputStream << someBytes
    

    will avoid the introspection which then makes it work on Tomcat 7.