ClassCastException: java.util.Collections$UnmodifiableMap cannot be cast to groovy.lang.Closure

597 views
Skip to first unread message

Tim van der Leeuw

unread,
Apr 22, 2015, 10:45:35 AM4/22/15
to grails-de...@googlegroups.com
Hi,

I'm getting a weird exception in DefaultConstraintEvaluator.evaluateConstraints() line 114 (Grails 2.5.0):

protected Map<String, Constrained> evaluateConstraints(
final Class<?> theClass, GrailsDomainClassProperty[] properties, boolean defaultNullable) {

boolean javaEntity = theClass.isAnnotationPresent(Entity.class);
LinkedList<?> classChain = getSuperClassChain(theClass);
Class<?> clazz;

ConstrainedPropertyBuilder delegate = new ConstrainedPropertyBuilder(theClass);

// Evaluate all the constraints closures in the inheritance chain
for (Object aClassChain : classChain) {
clazz = (Class<?>) aClassChain;
Closure<?> c = (Closure<?>) GrailsClassUtils.getStaticFieldValue(clazz, ConstraintsEvaluator.PROPERTY_NAME);

ClassCastException: java.util.Collections$UnmodifiableMap cannot be cast to groovy.lang.Closure

I have a hierarchy of beans annotated with @Validateable

For the first 2 classes in the classChain, the 'constraints' property of the class returns a Closure, as expected. However, for the final class in the class hierarchy, the field is instead an UnmodifiableMap containing entries of type <String,ConstrainedProperty>.

I have tried to reproduce the problem in a small sample-project but in that, it works. I haven't managed to find out what I need to do, to intentionally break it.

I have tried cleaning and re-compiling countless times, I have tried tweaking classes and included plugins, but so far no result - I'm stuck.

NB: In case it makes a difference, the constraint-evaluation is triggered from within the "fields" plugin when it tries to render an <f:display/> tag.

Does anyone have any clue why the 'constraints' property of a class might be seen as a Map of ConstrainedProperty entries?

Kind regards,

--Tim

Lari Hotari

unread,
May 4, 2015, 10:52:36 AM5/4/15
to grails-de...@googlegroups.com
Looks like a bug. Just wondering how it has been hiding so long.

This is probably a coincidence, a similar exception appeared some time ago:
https://github.com/grails/grails-core/commit/c18c769b
https://issues.apache.org/jira/browse/GROOVY-7308 . That bug is already fixed (2.3.11/2.4.2).
That's why your email catched my attention.


Does anyone have any clue why the 'constraints' property of a class might be seen as a Map of ConstrainedProperty entries?
Perhaps it should be calling the static getter method instead of accessing the field? That happened in my problem case.

I think this line:
        Closure<?> c = (Closure<?>) GrailsClassUtils.getStaticFieldValue(clazz, ConstraintsEvaluator.PROPERTY_NAME
);

should be
        Closure<?> c = (Closure<?>) GrailsClassUtils.getStaticPropertyValue(clazz, ConstraintsEvaluator.PROPERTY_NAME);

or even better it should be using the ClassPropertyFetcher which will cache reflection access for performance reasons and takes care preferring the static getters over direct field access.

Please open a new issue in GH for this.

Could you contribute a failing test? That's essential in getting this fixed. :)


-Lari
--
You received this message because you are subscribed to the Google Groups "Grails Dev Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-disc...@googlegroups.com.
To post to this group, send email to grails-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/grails-dev-discuss/5581ec8b-0d04-4edc-a64b-078dc26b4cce%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tim van der Leeuw

unread,
May 4, 2015, 11:20:46 AM5/4/15
to grails-de...@googlegroups.com
Hi,

The reason that it's been hiding so long, is that it is very hard to reproduce.

I have tried to create a small test-project to reproduce the problem, and nothing I did could actually reproduce it although I could reliably trigger it in my main application. Thus I also don't have a test-case to reproduce it, yet.

I did by now figure out that it is runtime induced behaviour: a page that works first time, would break with this exception after visiting a second page in the application.
Still I haven't been able to replicate this

I wonder if it is related to what happens WebMetaUtils.enhanceCommandObject() - although in the debugger, when seeing a Map of 'ConstrainedProperty' instances for the static 'constraints' property, the property 'grailsEnhanced' was not detected.

It is as if something calls the constraintsEvaluator, but doesn't know the right thing to do with the results - only I haven't yet been able to pinpoint wherefrom.

I'll post when I make more progress although for now, I've found some workarounds and am managing to avoid this  problem. For now I'm not yet opening an issue, since I feel that there's not enough information yet to go on - I want to have at least a path to reproduction outside of a large app.

Thanks for your reply,

--Tim
Reply all
Reply to author
Forward
0 new messages