Класс GroovyObject не найден на Tomcat 8 с войной Грааля 3.2.0
Я развернул Grails 3.2.0 WAR на Tomcat 8.5.6 и JDK 1.8.0_91 с простым контроллером, имеющим следующий код:
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
}
}
Этот код не выполняется со следующим исключением:
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
Перед созданием файла WAR я изменил встроенный tomcat на provided
в build.gradle
а также прокомментировал groovy-ant
зависимость, связанная с ядром Грааля #10196
Я вижу ответ здесь, но это не сработало, и приведенный выше код работает нормально, когда мы запускаем через grails run-app
,
Обновить
Я замкнул проблему. Это терпит неудачу только в этой части request.headerNames as List
1 ответ
Я почти уверен, что проблема заключается в использовании "как список". Главным образом потому, что Grails перезапишет реализацию Groovy asType, которая заставляет работать синтаксис приведения "как X".
Grails делает это, чтобы добавить поддержку таких вещей, как JSON для маршалинга известных типов Grails в форматы веб-транспорта. К сожалению, при этом Grails также нарушает любую функцию asType, которую вы могли объявить сами. Или в этом случае сам Groovy уже объявлен для преобразования перечисления в список.
Это довольно раздражает, так как Grails эффективно нарушает существующие контракты и заставляет вас изменять исходный код, чтобы он мог работать на Grails. Это или дамп Grails, потому что он не очень хорошо работает с совершенно корректным кодом Groovy.
Я считаю, что замена "в виде списка" .asType(List)
даже не решит проблему, так как вы все еще вызываете тот же код. В лучшем случае вы можете попробовать .collect([]) {it}
вместо. Возможно, нет необходимости добавлять пустой массив в качестве первого аргумента для сбора.