Open denis111 opened 9 years ago
Could you please provide a sample application or unit test that reproduces this issue? Please also include the stacktrace of the exception.
Here's the sample project https://drive.google.com/file/d/0B1TIQMQPXvOZemtpQWFUVV9ZeGs/view?usp=sharing . Just navigate to http://localhost:8080/fwith/my/index
I can confirm that this issue is still present in version 2.1.3 of the fields plugin. In my case the model attribute doesn't even matter. A simple <g:render template="something"/>
already causes the exception.
Edit: I believe I have found to source of this problem. This is not necessarily an error in the fields plugin itself, but an implementation error in Grails (not sure which versions are affected, I'm using 3.1.x).
In FormFieldsTagLib#getBeanStack()
there is a call to pageScope.hasVariable(STACK_PAGE_SCOPE_VARIABLE)
. The pageScope variable is of type GroovyPageBinding
, which is a hierarchical data structure: with each call to <g:render>
, a child pageScope is created with a reference to the parent scope. The Problem: the method hasVariable
was never overloaded to consider the hierarchical data structure, which means it will only find variables from child scope, but the bean stack variable was set in the parent scope! Because of this hasVariable
always returns false, which results in FormFieldsTagLib#getBeanStack()
creating a new empty stack. Setting the page scope variable with the new stack actually works in the hierarchy and overrides the existing one, which finally results in an EmptyStackException
because the stack was replaced by an empty one.
I will open an issue in the grails project for this error, as it does seem to be an error in the framework and not fields plugin.
I managed to fix the error in my application with the following groovy metaprogramming hack:
class BootStrap {
def init = {
FormFieldsTagLib.metaClass.getBeanStack = { getBeansStackPatched(delegate) }
}
private FormFieldsTagLib.BeanAndPrefixStack getBeansStackPatched(FormFieldsTagLib tagLib) {
Map variables = tagLib.pageScope.variables
if (!variables.containsKey(FormFieldsTagLib.STACK_PAGE_SCOPE_VARIABLE)) {
variables[FormFieldsTagLib.STACK_PAGE_SCOPE_VARIABLE] = new FormFieldsTagLib.BeanAndPrefixStack()
}
return variables[FormFieldsTagLib.STACK_PAGE_SCOPE_VARIABLE]
}
}