Menu

#92 Support Java 8 Defender methods (default methods)

2.3.26
closed-fixed
nobody
jdk8 (1)
5
2017-03-26
2013-10-31
Edvin Syse
No

Currently, Freemarker will not resolve default interface methods. Concider the following interface and implementation class:

public interface Named {
default String getName() {
return "Empty name";
}
}

public class Person implements Named {
}

If a Person is present in Freemarkers context as 'person', then 'person.name' should resolve.

Discussion

  • Dániel Dékány

    Thanks for the info, will try to fix this until Java 8 is out. (FreeMarker uses Java's BeanIntrospector facility for discovering properties and "actions", but then it seems for some reason it filters out what it finds.)

     
  • Edvin Syse

    Edvin Syse - 2013-11-01

    Cool! If anyone is interested, my workaround until then is implementing the generic get method in my context object like this (simplified code):

    public Object get(String key) {
        String getter = "get" + key.substring(0, 1).toUpperCase() + key.substring(1);
        Method method = getClass().getMethod(getter);
        return method.invoke(this);
    }
    
     
  • Dániel Dékány

    Problem is, FreeMarker works correctly; it uses java.beans.Introspector to know what JavaBean properties are available. And it seems default methods don't define JavaBean properties (unless you override them in a class, of course). I don't know if that's a conscious decision or an oversight in Java 8...

     

    Last edit: Dániel Dékány 2015-06-07
  • Edvin Syse

    Edvin Syse - 2014-03-31

    I agree, maybe it's best to leave it as it is. The workaround is simple enough :)

     
  • Dániel Dékány

    The same problem exists for non-getter methods too, since Freemarker also uses java.beans.Introspector for discovering them. Apparently, Java 8 default methods aren't even methods according to java.bean.Introspector. Anyone has link on why did the developers of the standard Java API decided so? Backward compatibility worries? Anyway... this is too much, so I think we will have to work this around after all.

     

    Last edit: Dániel Dékány 2015-06-07
  • Dániel Dékány

    • status: open --> open-accepted
    • Group: --> undecided
     
  • Dániel Dékány

    • Group: undecided --> 2.3.26
     
  • Dániel Dékány

    This is fixed in 2.3.26 (not yet released); see: https://issues.apache.org/jira/browse/FREEMARKER-24

     
  • Dániel Dékány

    • status: open-accepted --> closed-fixed
     
  • Dániel Dékány

    From 2.3.26 version 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.

     

Log in to post a comment.