Reputation: 19313
We've recently started to use java 8 default methods in interfaces, and looks like Freemarker can't see them:
${myRatings.notEmpty()}
The following has evaluated to null or missing:
==> myRatings.notEmpty
This is a pity because we're calling a bunch of methods in our templates. Is there a solution to this? Maybe some patches?
Internets speak mostly of getFoo() default methods which indeed make not much sense, but I'm talking about regular method calls, not getters.
Upvotes: 10
Views: 986
Reputation: 31122
Update: FreeMarker 2.3.26 has introduced a workaround for this. Quoted from the version history:
FREEMARKER-24: Added workaround (not enabled by default) to expose Java 8 default methods (and the bean properties they define) to templates, despite that
java.beans.Introspector
(the official JavaBeans introspector) ignores them, at least as of JRE 1.8.0_66. To enable this workaround, either increase the value of theincompatibleImprovements
constructor argument ofDefaultObjectWrapper
orBeansWrapper
used to 2.3.26, or set itstreatDefaultMethodsAsBeanMembers
setting totrue
. Note that if you leave theobject_wrapper
setting of theConfiguration
on its default, it's enough to increase theincompatibleImprovements
setting of theConfiguration
to 2.3.26, as that's inherited by the defaultobject_wrapper
.
Original answer:
How Freemarker sees objects is based on the JavaBeans specification, which is a cornerstone of many Java technologies. It introspects classes with java.beans.Introspector
to ensure conformance. Apparently, JavaBeans doesn't support Java 8 default methods. BeanInfo.getMethodDescriptors()
doesn't return the default methods, and we have the same problem with BeanInfo.getPropertiesDescriptors()
with getters. I don't know why did the maintainers of the standard Java API (or of JavaBeans) decided like so... Certainly sooner or later Freemarker will have to do an extra round of introspection to work around these JavaBeans limitations.
Upvotes: 15