import java.io.StringReader; import java.io.StringWriter; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import freemarker.core.Environment; import freemarker.ext.beans.BeansWrapper; import freemarker.template.Configuration; import freemarker.template.Template; public final class FreemarkerBug { protected static BeansWrapper defaultWrapper = BeansWrapper.getDefaultInstance(); protected static Configuration defaultConfig = makeConfiguration(defaultWrapper); // based on ofbiz public static Configuration makeConfiguration(BeansWrapper wrapper) { Configuration newConfig = new Configuration(); newConfig.setObjectWrapper(wrapper); newConfig.setSharedVariable("Static", wrapper.getStaticModels()); newConfig.setLocalizedLookup(false); return newConfig; } public static String renderTemplate(String location, String templateBody, Map context) throws Exception { Template template = new Template(location, new StringReader(templateBody), defaultConfig); StringWriter out = new StringWriter(); Environment env = template.createProcessingEnvironment(context, out); env.process(); return out.toString(); } public static String m(String name, List list) { return "<(" + name + "):" + (list != null ? list.toString() : null) + ">"; } public static String m(Object... args) { return "<+" + (args != null ? Arrays.asList(args).toString() : null) + ">"; } public static void main(String[] args) throws Exception { String badTemplate = "${Static['FreemarkerBug'].m('foo', null)}"; Map context = new HashMap(); String result = renderTemplate("bad-template", badTemplate, context); System.out.println("result=" + result); } }