grails-core
grails-core copied to clipboard
Grails 4.0.12 and 5.0.1: VERY strange behavior in controller action using enumeration
We did upgrade some production application of ours to Grails 4.0.12 from 3.3.x and some specific code suddenly stopped working. I managed to extract a minimal example application with similar code, which produces the exception. I also added some Spock tests which verify the problem. Additionally I also tried with the newest Grails version 5.0.1, but the problem is still present there.
grails-app/controllers/myapp/TestController.groovy
package myapp
import groovy.util.logging.Slf4j
import myapp.utils.UIState
@Slf4j // works if @Slf4j is removed
class TestController {
// works if parameter name is changed from someState to something else
def something(String someState) {
render 'something'
}
private UIState getUIState() {
// works if variable someState is changed to something else
UIState.SomeState someState = UIState.SomeState.NORMAL
return new UIState(state: someState)
}
}
src/main/groovy/myapp/utils/UIState.groovy
package myapp.utils
import groovy.transform.Immutable
@Immutable
class UIState {
enum SomeState { NORMAL, THING, THINGY }
SomeState state = SomeState.NORMAL
}
This produces an java.lang.IllegalArgumentException: No enum constant myapp.utils.UIState.SomeState.
when I open the URL http://localhost:8080/test/something?someState= inside the browser.
What is very strange in this code is the fact, that when I change only one of the marked lines above (see my comments in the code), the example suddenly starts working. Also I don't understand why in the non-working example some Enum.valueOf
call seems to happen, but in my very simple controller code the action something
doesn't utilize the parameter and it is not even an enumeration. Also the private utility method getUIState
is not invoked at all and why the presence of the @Slf4j
annotation changes the behavior is very unclear to me.
Task List
- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [x] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)
Steps to Reproduce
- clone example repository
-
grails run-app
-
curl http://localhost:8080/test/something?someState=
- or
./gradlew test
Expected Behaviour
I don't see why the given example should not work.
Actual Behaviour
Grails application running at http://localhost:8080 in environment: development
2021-11-22 21:43:37.729 ERROR --- [nio-8080-exec-3] o.g.web.errors.GrailsExceptionResolver : IllegalArgumentException occurred when processing request: [GET] /test/something - parameters:
someState:
No enum constant myapp.utils.UIState.SomeState.. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.IllegalArgumentException: No enum constant myapp.utils.UIState.SomeState.
at java.base/java.lang.Enum.valueOf(Enum.java:240)
... 15 common frames omitted
Environment Information
- Operating System: Windows 11 / Ubuntu 18.04 running in WSL
- Grails Version: 4.0.12 / 5.0.1
- JDK Version: 11
Example Application
https://github.com/davidkron/grails-strange-controller-action-problem