Shashank Agrawal
Shashank Agrawal

Reputation: 25797

GroovyObject class not found on Tomcat 8 with war of Grails 3.2.0

I deployed a Grails 3.2.0 WAR on Tomcat 8.5.6 and JDK 1.8.0_91 with a simple controller having following code:

package com.test

class MailController {
    static responseFormats = ['json']

    def index() {
        Map headers = (request.headerNames as List).collectEntries {    // It fails on this line
            return [(it): request.getHeader(it)]
        }

        println "Incoming email $headers"
        render status: 200
    }
}

This code fails with the following exception:

Caused by: java.lang.NoClassDefFoundError: groovy/lang/GroovyObject
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at groovy.util.ProxyGenerator.instantiateDelegateWithBaseClass(ProxyGenerator.java:225)
    at groovy.util.ProxyGenerator.instantiateDelegateWithBaseClass(ProxyGenerator.java:193)
    at groovy.util.ProxyGenerator.instantiateDelegate(ProxyGenerator.java:185)
    at groovy.util.ProxyGenerator.instantiateDelegate(ProxyGenerator.java:181)
    at org.grails.web.converters.ConverterUtil.invokeOriginalAsTypeMethod(ConverterUtil.java:161)
    at org.grails.web.converters.ConvertersExtension.asType(ConvertersExtension.groovy:56)
    at com.test.MailController.index(MailController.groovy:7)
    at org.grails.core.DefaultGrailsControllerClass$MethodHandleInvoker.invoke(DefaultGrailsControllerClass.java:222)
    at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:187)
    at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    ... 14 common frames omitted
Caused by: java.lang.ClassNotFoundException: groovy.lang.GroovyObject
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    ... 27 common frames omitted

Before building the WAR file, I've changed the embedded tomcat to provided in build.gradle and also commented the groovy-ant dependency related to grails-core#10196

I see a answer here but that didn't worked and the above code is working fine when we run via grails run-app.

Update

I shorted down the issue. It is failing on this part only request.headerNames as List

Upvotes: 1

Views: 209

Answers (1)

Sebastian Gozin
Sebastian Gozin

Reputation: 9

I am pretty sure the problem is with the use of "as List". Mostly because Grails will overwrite Groovy's asType implementation which makes the "as X" coercion syntax work.

Grails does this to add support for things like JSON for marshalling known Grails types to web transport formats. Unfortunately, in doing so Grails also breaks any asType function you might have declared yourself. Or in this case Groovy itself already declared for converting an Enumeration into a List.

It's quite annoying as Grails is effectively breaking existing contracts here and forcing you to modify upstream code to allow it to run on Grails. That or dump Grails because it doesn't play nice with perfectly valid Groovy code.

I believe replacing "as List" with .asType(List) won't even fix the issue as you're still invoking the same code. At best you could try .collect([]) {it} instead. It may not be necessary to add the empty array as the first argument to collect.

Upvotes: 1

Related Questions