Unable to call Java 8 default methods
Generates text that depends on changing data (like dynamic HTML).
Brought to you by:
revusky
Hello,
I have a interface with a Java8 default method, apparently it is not possible to call a default method from a freemarker template.
public interface Test { default String getTest() { return "Test"; } } public class TestImpl implements Test { }
Freemarker Template:
${testImpl.test}
Results in:
freemarker.core.InvalidReferenceException: The following has evaluated to null or missing.
I think the reason is that ClassIntrospector is using clazz.getMethods() which is not including default methods.
Gregor
As far as I see, the reason is that FreeMarker uses
java.beans.Introspector
for discovering JavaBean properties and that doesn't treat default getter methods as JavaBean property readers. It's either a Java 8 bug, or for some reason they have decided that default methods don't define JavaBean properties.Last edit: Dániel Dékány 2015-01-22
I guess its related to this bug:
https://bugs.openjdk.java.net/browse/JDK-8071693
Seems that Java won't react to this fast enough, or maybe ever... We will have to add some hack to address this.
From 2.3.26 verison history: 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 the incompatibleImprovements constructor argument of DefaultObjectWrapper or BeansWrapper the used to 2.3.26, or set its treatDefaultMethodsAsBeanMembers setting to true. Note that if you leave the object_wrapper setting of the Configuration on its default, it's enough to increase the incompatibleImprovements setting of the Configuration to 2.3.26, as that's inherited by the default object_wrapper.