Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Freemarker and java8 default methods?

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.

like image 560
alamar Avatar asked May 28 '15 10:05

alamar


People also ask

What is FreeMarker used for?

Apache FreeMarker™ is a template engine: a Java library to generate text output (HTML web pages, e-mails, configuration files, source code, etc.) based on templates and changing data.

What is FreeMarker template engine?

FreeMarker is a "template engine"; a generic tool to generate text output (anything from HTML to autogenerated source code) based on templates. It's a Java package, a class library for Java programmers. It's not an application for end-users in itself, but something that programmers can embed into their products.

What is free markup language?

FreeMarker is a template engine, written in Java, and maintained by the Apache Foundation. We can use the FreeMarker Template Language, also known as FTL, to generate many text-based formats like web pages, email, or XML files.

What is FTL template?

An FTL file is a template used by FreeMarker, a Java template engine used to auto-generate text output. It contains source text as well as FreeMarker variable definitions and instructions that are used as placeholders for text substitutions. FTL files are commonly used for auto-generating HTML webpages, .


1 Answers

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 the incompatibleImprovements constructor argument of DefaultObjectWrapper or BeansWrapper 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.

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.

like image 187
ddekany Avatar answered Oct 27 '22 00:10

ddekany