http://git-wip-us.apache.org/repos/asf/incubator-freemarker-site/blob/52c070a9/builds/2.3.26-nightly/versions_2_3_21.html ---------------------------------------------------------------------- diff --git a/builds/2.3.26-nightly/versions_2_3_21.html b/builds/2.3.26-nightly/versions_2_3_21.html new file mode 100644 index 0000000..6740ac9 --- /dev/null +++ b/builds/2.3.26-nightly/versions_2_3_21.html @@ -0,0 +1,1419 @@ +<!doctype html> +<!-- Generated by FreeMarker/Docgen from DocBook --> +<html lang="en" class="page-type-section"> +<head prefix="og: http://ogp.me/ns#"> +<meta charset="utf-8"> +<title>2.3.21 - Apache FreeMarker Manual</title> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> +<meta name="viewport" content="width=device-width,initial-scale=1"> +<meta name="format-detection" content="telephone=no"> +<meta property="og:site_name" content="Apache FreeMarker Manual"> +<meta property="og:title" content="2.3.21"> +<meta property="og:locale" content="en_US"> +<meta property="og:url" content="http://freemarker.org/docs/versions_2_3_21.html"> +<link rel="canonical" href="http://freemarker.org/docs/versions_2_3_21.html"> +<link rel="icon" href="favicon.png" type="image/png"> +<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Roboto:500,700,400,300|Droid+Sans+Mono"> +<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1489402528979"> +<script> +(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ +(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), +m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) +})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); +ga('create', 'UA-55420501-1', 'auto'); +ga('send', 'pageview'); +</script> +</head> +<body itemscope itemtype="https://schema.org/Code"> + <meta itemprop="url" content="http://freemarker.org/docs/"> + <meta itemprop="name" content="Apache FreeMarker Manual"> + + <!--[if lte IE 9]> + <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div> + <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner"> <img itemprop="image" src="logo.png" alt="FreeMarker"> +</a><ul class="tabs"><li><a href="http://freemarker.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/browse/FREEMARKER/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">Manual</a><div class="navigation-header"></div><form method="get" class="search-form" action="search-results.html"><fieldset><legend class="sr-only">Search form</legend><label for="search-field" class="sr-only">Search query</label><input id="searc h-field" name="q" type="search" class="search-input" placeholder="Search" spellcheck="false" autocorrect="off" autocomplete="off"><button type="submit" class="search-btn"><span class="sr-only">Search</span></button></fieldset></form></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">Apache FreeMarker Manual</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app.html"><span itemprop="name">Appendixes</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app_versions.html"><span itemprop="name">Version history</span></a></li><li class="step-3" itemprop="itemListEl ement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="versions_2_3_21.html"><span itemprop="name">2.3.21</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div> <div class="main-content site-width"> + <div class="content-wrapper"> + <div id="table-of-contents-wrapper" class="col-left"> + <script>var breadcrumb = ["Apache FreeMarker Manual","Appendixes","Version history","2.3.21"];</script> + <script src="toc.js?1489402528979"></script> + <script src="docgen-resources/main.min.js?1489402528979"></script> + </div> +<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="versions_2_3_22.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_20.html"><span>Next</span></a></div><div class="title-wrapper"> +<h1 class="content-header header-section1" id="versions_2_3_21" itemprop="headline">2.3.21</h1> +</div></div><div class="page-menu"> +<div class="page-menu-title">Page Contents</div> +<ul><li><a class="page-menu-link" href="#autoid_171" data-menu-target="autoid_171">Changes on the FTL side</a></li><li><a class="page-menu-link" href="#autoid_172" data-menu-target="autoid_172">Changes on the Java side</a></li><li><a class="page-menu-link" href="#autoid_173" data-menu-target="autoid_173">Other changes</a></li></ul> </div><p>Date of release: 2014-10-12</p><p>Note that since 2.3.21 is designed to be fully backward + compatible with the previous 2.3.x releases, <em>some of the + improvements and fixes described below are only activated when you + specifically ask for 2.3.21 "incompatible + improvements"</em>, because they could, with very small + chance, break existing applications. If the dependent project is still + actively developed, allowing 2.3.21 "incompatible improvements" is + highly recommended. See <a href="pgui_config_incompatible_improvements.html#pgui_config_incompatible_improvements_how_to_set">how to set + "incomplatible improvements" here</a>.</p><p>Note that we have changed our proprietary BSD-style license to + Apache License, Version 2.0. See the <a href="app_license.html">new + license here</a>.</p><p>Note that the minimum required Java version was increased from + 1.2 to 1.4.</p> + + + + +<h2 class="content-header header-section2" id="autoid_171">Changes on the FTL side</h2> + + + <ul> + <li> + <p>Improved ranges:</p> + + <ul> + <li> + <p>Added ranges with exclusive end: + <code class="inline-code"><em class="code-color">start</em>..<<em class="code-color">end</em></code> + (also can be written as + <code class="inline-code"><em class="code-color">start</em>..!<em class="code-color">end</em></code>). + <a href="dgui_template_exp.html#dgui_template_exp_direct_ranges">More...</a></p> + </li> + + <li> + <p>Added length limited ranges: + <code class="inline-code"><em class="code-color">start</em>..*<em class="code-color">length</em></code>: + For example, <code class="inline-code">10..*4</code> gives <code class="inline-code">[10, + 11, 12, 13]</code>, <code class="inline-code">10..*-4</code> gives + <code class="inline-code">[10, 9, 8, 7]</code>, and + <code class="inline-code">10..*0</code> gives <code class="inline-code">[]</code>. When + these kind of ranges are used for slicing, the slice will + end without error if the end of the sliced sequence or + string is reached before the specified range length was + reached. Thus, for example, to take the first 10 characters + from the string <code class="inline-code">s</code>, or less if + <code class="inline-code">s</code> is shorter than 10 characters, you can + use <code class="inline-code">s[0..*10]</code>. <a href="dgui_template_exp.html#dgui_template_exp_seqenceop_slice">More...</a></p> + </li> + + <li> + <p>Square bracket now accepts range values from any + source, like <code class="inline-code"><#assign r = 1..3> + ${'foobar'[r]}</code> will print + <code class="inline-code">"oob"</code>. Earlier it has only supported + ranges that were specified directly inside the square + brackets, like <code class="inline-code">'foobar'[1..3]</code>.</p> + </li> + + <li> + <p>When slicing a sequence with a right-unbounded range, + it's now allowed to have a range start index that's one + higher than the last index of the sliced sequence. For + example, <code class="inline-code">['x', 'y'][2..]</code> is not an error + anymore, but an empty sequence. (Of course, <code class="inline-code">['x', + 'y'][3..]</code> is still an error.)</p> + </li> + + <li> + <p><code class="inline-code"><em class="code-color">someString</em>?substring(<em class="code-color">from</em>, + <em class="code-color">toExclusive</em>)</code> and + <code class="inline-code"><em class="code-color">someString</em>?substring(<em class="code-color">from</em>)</code> + are now deprecated; use this slicing expression instead: + <code class="inline-code"><em class="code-color">someString</em>[<em class="code-color">from</em>..<<em class="code-color">toExclusive</em>]</code> + and + <code class="inline-code"><em class="code-color">someString</em>[<em class="code-color">from</em>..]</code>. + A warning if you are processing XML: Since slicing + expressions work both for sequences and strings, and XML + nodes in FTL are typically both sequences and strings at the + same time, there the equivalent expression is + <code class="inline-code"><em class="code-color">someXmlNode</em>?string[<em class="code-color">from</em>..<<em class="code-color">toExclusive</em>]</code> + and + <code class="inline-code"><em class="code-color">exp</em>?string[<em class="code-color">from</em>..]</code>, + because without the <code class="inline-code">?string</code> it would + slice the node sequence instead of the text value of the + node.</p> + </li> + + <li> + <p>If the <code class="inline-code">incompatible_improvements</code> in + the FreeMarker configuration is set to at least 2.3.21, + right-unbounded ranges become readable (like + <code class="inline-code">#list</code>-able). Earlier they could only be + used for slicing, and behaved like empty sequences + otherwise.</p> + </li> + </ul> + </li> + + <li> + <p>New built-in, <code class="inline-code">?url_path</code>: This is the + same as <a href="ref_builtins_string.html#ref_builtin_url">the + <code>url</code> built-in</a>, except that it doesn't + escape slash (<code class="inline-code">/</code>) characters. This meant to be + used for converting paths (like paths coming from the OS or some + content repository) that use slash (not backslash!) to a path + the can be inserted into the path part of an URL.</p> + </li> + + <li> + <p>New built-ins for string manipulation:</p> + + <ul> + <li> + <p><code class="inline-code"><em class="code-color">someString</em>?keep_before(<em class="code-color">substring</em>[, + <em class="code-color">flags</em>])</code>: <a href="ref_builtins_string.html#ref_builtin_keep_before">More...</a></p> + </li> + + <li> + <p><code class="inline-code"><em class="code-color">someString</em>?keep_after(<em class="code-color">substring</em>[, + <em class="code-color">flags</em>])</code>: <a href="ref_builtins_string.html#ref_builtin_keep_after">More...</a></p> + </li> + + <li> + <p><code class="inline-code"><em class="code-color">someString</em>?remove_beginning(<em class="code-color">substring</em>)</code>: + <a href="ref_builtins_string.html#ref_builtin_remove_beginning">More...</a></p> + </li> + + <li> + <p><code class="inline-code"><em class="code-color">someString</em>?remove_ending(<em class="code-color">substring</em>)</code>: + <a href="ref_builtins_string.html#ref_builtin_remove_ending">More...</a></p> + </li> + + <li> + <p><code class="inline-code"><em class="code-color">someString</em>?ensure_starts_with(<em class="code-color">substring</em>[, + <em class="code-color">substitution</em>[, + <em class="code-color">flags</em>]])</code>: <a href="ref_builtins_string.html#ref_builtin_ensure_starts_with">More...</a></p> + </li> + + <li> + <p><code class="inline-code"><em class="code-color">someString</em>?ensure_ends_with(<em class="code-color">substring</em>)</code>: + <a href="ref_builtins_string.html#ref_builtin_ensure_ends_with">More...</a></p> + </li> + </ul> + </li> + + <li> + <p><code class="inline-code"><em class="code-color">someString</em>?number</code> + now recognizes all XML Schema number formats, like + <code class="inline-code">NaN</code>, <code class="inline-code">INF</code>, + <code class="inline-code">-INF</code>, plus the Java-native formats + <code class="inline-code">Infinity</code> and + <code class="inline-code">-Infinity</code>.</p> + </li> + + <li> + <p>If <code class="inline-code">incompatible_improvements</code> in the + FreeMarker configuration is set to at least 2.3.21, + <code class="inline-code"><em class="code-color">someNumber</em>?c</code> will + return <code class="inline-code">"INF"</code>, <code class="inline-code">"-INF"</code> and + <code class="inline-code">"NaN"</code> for positive/negative infinity and IEEE + floating point Not-a-Number, respectively. These are the XML + Schema compatible representations of these special values. + Earlier it has returned what + <code class="inline-code">java.text.DecimalFormat</code> did with US locale, + none of which was understood by any (common) computer + language.</p> + </li> + + <li> + <p>New built-in: + <code class="inline-code"><em class="code-color">someString</em>?boolean</code>. + This is for example useful for converting "true" and "false" + strings coming from XML to real boolean values. <a href="ref_builtins_string.html#ref_builtin_boolean">More...</a></p> + </li> + + <li> + <p>Date/time/date-time related changes:</p> + + <ul> + <li> + <p>Added new kind of + <code class="inline-code">date_format</code>/<code class="inline-code">datetime_format</code>/<code class="inline-code">time_format</code> + setting values: XML Schema formats, starting with + <code class="inline-code">"xs"</code> and ISO 8601:2004 formats, starting + with <code class="inline-code">"iso"</code>. The format string can be + continued with various space (or <code class="inline-code">_</code>) + separated options, like <code class="inline-code">h</code> or + <code class="inline-code">m</code> or <code class="inline-code">s</code> or + <code class="inline-code">ms</code> for setting shown accuracy, + <code class="inline-code">nz</code> or <code class="inline-code">fz</code> for setting + time zone offset visibility, and <code class="inline-code">u</code> or, + <code class="inline-code">fu</code> for using UTC time zone . For example, + to use ISO 8601 with minute precision and without the zone + offset being shown, set the + <code class="inline-code">datetime_format</code> setting to <code class="inline-code">"iso + m nz"</code>, so then the output will be like + <code class="inline-code">2014-09-03T20:56</code>. <a href="ref_directive_setting.html#topic.dateTimeFormatSettings">More...</a></p> + </li> + + <li> + <p>Because anything that's accepted as + <code class="inline-code">date_format</code>/<code class="inline-code">datetime_format</code>/<code class="inline-code">time_format</code> + setting value can also be used with the + <code class="inline-code">?string</code> and + <code class="inline-code">?date</code>/<code class="inline-code">?time</code>/<code class="inline-code">?datetime</code> + build-ins, you can use the new formats like + <code class="inline-code">someDate?string.xs</code> and + <code class="inline-code">someString?date.xs</code>. (For the + <code class="inline-code">"xs"</code> and <code class="inline-code">"iso"</code> + formats, <code class="inline-code">_</code> can be used instead of space, + which means that, for example, you can write + <code class="inline-code">lastModified?string.iso_m_u</code> instead of + the more verbose <code class="inline-code">lastModified?string["iso m + u"]</code>.)</p> + </li> + + <li> + <p>That <code class="inline-code">"iso"</code> and + <code class="inline-code">"xs"</code> are now possible + <code class="inline-code">date_format</code>/<code class="inline-code">datetime_format</code>/<code class="inline-code">time_format</code> + setting values also means that such values can now be parsed + too via + <code class="inline-code">?date</code>/<code class="inline-code">?time</code>/<code class="inline-code">?datetime</code>. + The main application is with processing XML DOM-s, as there + values are coming in as strings, and now you can do + something like <code class="inline-code">order.confirmDate?date.xs</code> + to convert them to real dates.</p> + </li> + + <li> + <p>The <a href="ref_builtins_date.html#ref_builtin_date_iso"><code>?iso_...</code> + built-ins</a> are now deprecated in favor of the new + setting values described above. They can be set as the + default date/time/date-time format, seamlessly fit into the + formatting architecture (and thus can parse strings too), + and has more/better options (<code class="inline-code">ms</code> always + shows 3 millisecond digits, <code class="inline-code">fz</code> for + forcing showing time zone offset).</p> + </li> + + <li> + <p>If the "incompatible improvements" + configuration setting is at least 2.3.21, the + <code class="inline-code">?iso_...</code> built-ins won't show time zone + offset for <code class="inline-code">java.sql.Time</code> values anymore. + Most databases store time values that aren't in any time + zone, but just store hour, minute, second, and decimal + second field values, so showing the time zone doesn't make + sense. (Notable exceptions are PostgreSQL "time with time + zone" columns, where + <code class="inline-code"><em class="code-color">mzTime</em>?string.iso_fz</code> + could be used.)</p> + </li> + + <li> + <p>Added <code class="inline-code">?is_time</code>, + <code class="inline-code">?is_datetime</code>, + <code class="inline-code">?is_date_only</code> (should be called + <code class="inline-code">?is_date</code>, but that was already taken) and + <code class="inline-code">?is_unknown_date_like</code> to check the exact + type of a date-like value.</p> + </li> + + <li> + <p><code class="inline-code">?is_date</code> is now a deprecated name, + use <code class="inline-code">?is_date_like</code> instead. This is + because <code class="inline-code">?is_date</code> sounds like it checks if + the value is a date without time part, but actually it also + returns <code class="inline-code">true</code> for time, date-time, and + unknown date-like values.</p> + </li> + + <li> + <p>Added <code class="inline-code">?date_if_unknown</code>, + <code class="inline-code">?time_if_unknown</code> and + <code class="inline-code">?datetime_if_unknown</code> built-ins, which + mark a date-like value with some of the sub-types: date + without time, time, or date-time, respectively. However, if + the value already holds this information, the built-in has + no effect. That is, it will never convert the sub-type of a + value, it only adds the sub-type if it was unknown.</p> + </li> + + <li> + <p>Bug fixed: ISO 8601 dates (via + <code class="inline-code">?iso_...</code> and <code class="inline-code">"iso"</code> + format settings) now use proleptic Gregorian calendar for + the years before 1582, rather than Julian calendar. This is + (indirectly) required by the standard, and it's also how the + default Sun/Oracle Java XML Schema date/time/dateTime parser + works.</p> + </li> + </ul> + </li> + + <li> + <p>Error message quality improvements (targeting frequent + support requests and some error message bugs):</p> + + <ul> + <li> + <p>Fixed glitch where if an <code class="inline-code">#if</code> had + and <code class="inline-code">#else</code> or <code class="inline-code">#elseif</code>, + the + <code class="inline-code">#if</code>/<code class="inline-code">#else</code>/<code class="inline-code">#elseif</code> + wasn't hidden in the FTL stack trace when the error was + inside its nested block.</p> + </li> + + <li> + <p>Some new context sensitive hints in undefined variable + exception error messages.</p> + </li> + + <li> + <p>Fixed unclosed directive error messages at end of file + where the wrong unclosed directive name was reported</p> + </li> + + <li> + <p>Better type error messages when accessing XML data + (applies when wrapped with + <code class="inline-code">freemarker.ext.dom</code>):</p> + + <ul> + <li> + <p>Trying to use + <code class="inline-code">node.<em class="code-color">noSuchChildNodes</em></code> + on a place where scalar value is expected will explain + that the problem is that you had no matches in the + constructing XML query.</p> + </li> + + <li> + <p>Trying to use + <code class="inline-code">node.<em class="code-color">multipleSuchChildNodes</em></code> + on a place where scalar value is expected will explain + that the problem is that you had multiple matches in the + constructing XML query.</p> + </li> + + <li> + <p>Trying to use + <code class="inline-code">node.<em class="code-color">exactlyOneChildNode</em></code> + as number, date/time/date-time or boolean will explain + that values coming from XML are always strings (text), + and must be converted explicitly via + <code class="inline-code">?number</code>, <code class="inline-code">?boolean</code>, + <code class="inline-code">?date.xs</code>, etc.</p> + </li> + </ul> + </li> + + <li> + <p>Trying to use <code class="inline-code">obj.someMethod</code> + without <code class="inline-code">()</code> on a place where method value + is not expected will recommend calling the method.</p> + </li> + + <li> + <p>Trying to use methods like + <code class="inline-code">obj.getFoo</code> or + <code class="inline-code">obj.isFoo</code> without <code class="inline-code">()</code>on + a place where method value is not expected will recommend + using the <code class="inline-code">obj.foo</code> form.</p> + </li> + + <li> + <p>Messages are now much more readable when rendered in + environments that don't obey to line-breaks. (This often + happens in improperly implemented HTML error pages and logs + viewers.)</p> + </li> + + <li> + <p>Better FTL instruction stack traces:</p> + + <ul> + <li> + <p>Error messages now contain up to 10 lines of FTL + stack trace (unless it's on the top of a full FTL stack + trace), because the FTL stack trace wasn't printed at + all when the exception was a cause exception in a Java + stack trace, or when only the value of + <code class="inline-code">getMessage()</code> was printed instead of a + stack trace.</p> + </li> + + <li> + <p>The FTL stack trace is now more self explanatory + as it contains more text labels.</p> + </li> + + <li> + <p>Stack frames that belong to nestings are now + marked differently, and are filtered out when the stack + trace wouldn't fit into the error message + otherwise.</p> + </li> + </ul> + </li> + + <li> + <p>Bug fixed: <code class="inline-code">?substring</code> has thrown + low level + <code class="inline-code">java.lang.IndexOutOfBoundsException</code>-s + instead of more descriptive + <code class="inline-code">TemplateModelException</code>-s with FTL stack + trace.</p> + </li> + + <li> + <p>Bug fixed: Slicing with ranges sometimes thrown low + level + <code class="inline-code">java.lang.IndexOutOfBoundsException</code>-s + instead of more descriptive + <code class="inline-code">TemplateModelException</code>-s with FTL stack + trace.</p> + </li> + + <li> + <p>Bug fixed [<a href="https://sourceforge.net/p/freemarker/bugs/402/">402</a>]: + Fixed misleading parser error message when a directive + called without its required parameters (like + <code class="inline-code"><#list></code>) was reported as unknown + directive.</p> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/222/">222</a>]: + Poor quality error message when + <code class="inline-code"><em class="code-color">someString</em>[<em class="code-color">someIndex</em>]</code> + fails with string index out of bounds.</p> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/27/">27</a>]: + Not very good quality error messages when + <code class="inline-code">#import</code>-ing a template whose parsing + fails.</p> + </li> + </ul> + </li> + + <li> + <p>New <code class="inline-code">include</code> directive option, + <code class="inline-code">ignore_missing=<em class="code-color">boolean</em></code>. + When this is set to <code class="inline-code">true</code>, and the template to + include is missing, the error will be silently ignored, and + nothing will be included.</p> + </li> + + <li> + <p>The <code class="inline-code">setting</code> directive can now set the + <code class="inline-code">output_encoding</code> setting.</p> + </li> + + <li> + <p>New special variable: <code class="inline-code">.locale_object</code>. + This is like <code class="inline-code">.locale</code>, except that it's a + <code class="inline-code">java.util.Locale</code> object, not a string. This + is handy if you want to pass the current locale to Java + methods.</p> + </li> + + <li> + <p>If <code class="inline-code">incompatible_improvements</code> in the + FreeMarker configuration is set to at least 2.3.21, hash + <em>literals</em> that repeat keys now only have the + key once with <code class="inline-code">?keys</code>, and only has the last + value associated to that key with <code class="inline-code">?values</code>. + This is consistent with the behavior of + <code class="inline-code"><em class="code-color">hash</em>[<em class="code-color">key</em>]</code> + and how maps work in Java.</p> + </li> + + <li> + <p>Bug fixed: <code class="inline-code">?is_enumerable</code> has returned + <code class="inline-code">true</code> for Java methods get from Java objects, + despite that those values aren't <code class="inline-code"><#list + ...></code>-able. (This is actually a historical quirk of + <code class="inline-code">BeansWrapper</code>, not a bug in + <code class="inline-code">?is_enumerable</code>, but now + <code class="inline-code">?is_enumerable</code> is aware of this exceptional + case.)</p> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/257/">257</a>]: + The result value of <code class="inline-code">?matches</code> wasn't + "reentrant". For example, you couldn't list the + matches inside another listing where you are also listing + exactly the same result value (stored in a common variable), as + they would consume from the same iterator. Most importantly, + even accessing the <code class="inline-code">?size</code> of the same result + value has terminated the outer listing of the same value.</p> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/229/">229</a>]: + If you set <code class="inline-code">incompatible_improvements</code> to + 2.3.21 (or higher), unclosed comments (<code class="inline-code"><#-- + <em class="code-color">...</em></code>) and + <code class="inline-code">#noparse</code>-s won't be silently closed at the + end of template anymore, but cause a parsing error + instead.</p> + </li> + </ul> + + + + + +<h2 class="content-header header-section2" id="autoid_172">Changes on the Java side</h2> + + + <ul> + <li> + <p>Added new <code class="inline-code">Configuration</code> constructor, + <code class="inline-code">Configuration(Version + incompatibleImprovements)</code>. This deprecates the vague + <code class="inline-code">Configuration()</code> constructor, and makes using + <code class="inline-code">setIncompatibleImprovements(Version)</code> needless + in most cases. See an example <a href="pgui_quickstart_createconfiguration.html">here...</a></p> + </li> + + <li> + <p>When setting the + <code class="inline-code">incompatible_improvements</code> setting (like with + the constructor above) to 2.3.21, two setting defaults + change:</p> + + <ul> + <li> + <p>The default of the <code class="inline-code">object_wrapper</code> + setting + (<code class="inline-code">Configuration.getObjectWrapper()</code>) + changes from + <code class="inline-code">ObjectWrapper.DEFAULT_WRAPPER</code> to another + almost identical <code class="inline-code">DefaultObjectWrapper</code> + singleton, returned by <code class="inline-code">new + DefaultObjectWrapperBuilder(Version).build()</code>. The + new default object wrapper's "incompatible + improvements" version is set to the same as of the + <code class="inline-code">Configuration</code>. (See later regarding the + 2.3.21 "incompatible improvements" of + <code class="inline-code">BeansWrapper</code> and + <code class="inline-code">DefaultObjectWrapper</code>). Furthermore, the + new default object wrapper doesn't allow changing its + settings; setter methods will throw + <code class="inline-code">IllegalStateException</code>. (If anything tries + to call setters on the old default in your application, + that's a dangerous bug that won't remain hidden now. As the + old default is a singleton too, potentially shared by + independently developed components, most of them expects the + out-of-the-box behavior from it (and the others are + necessarily buggy). Also, then concurrency glitches can + occur (and even pollute the class introspection cache) + because the singleton is modified after publishing.)</p> + </li> + + <li> + <p>The default of the <code class="inline-code">template_loader</code> + setting + (<code class="inline-code">Configuration.getTemplateLoader()</code>}) + changes to <code class="inline-code">null</code>, which means that + FreeMarker will not find any templates. Earlier the default + was a <code class="inline-code">FileTemplateLoader</code> that used the + current directory as the root. This was dangerous and + fragile as you usually don't have good control over what the + current directory will be. Luckily, the old default almost + never looked for the templates at the right place anyway, so + pretty much all applications had to set + <code class="inline-code">template_loader</code>, so it's unlikely that + changing the default breaks your application.</p> + </li> + </ul> + </li> + + <li> + <p>New <code class="inline-code">BeansWrapper</code>, + <code class="inline-code">DefaultObjectWrapper</code> and + <code class="inline-code">SimpleObjectWrapper</code> constructor that takes a + <code class="inline-code">Version</code> + <code class="inline-code">incompatibleImprovements</code> argument. This has + the same role as the + <code class="inline-code">incompatible_improvements</code> setting of the + <code class="inline-code">Configuration</code>, but it applies to the + <code class="inline-code">ObjectWrapper</code> instead. (As + <code class="inline-code">ObjectWrapper</code>-s are often shared among + multiple <code class="inline-code">Configuration</code>-s, so they can't use + that setting of the <code class="inline-code">Configuration</code>.) In new or + actively developed projects it's recommended to use + <code class="inline-code">Configuration.VERSION_2_3_21</code> now. The + constructor without the <code class="inline-code">Version</code> parameter is + now deprecated.</p> + </li> + + <li> + <p>Safer and more memory-efficient way of managing singletons + of <code class="inline-code">DefaultObjectWrapper</code>-s and + <code class="inline-code">BeansWrapper</code>-s that are possibly shared by + independently developed subsystems:</p> + + <ul> + <li> + <p>Instead of <code class="inline-code">new + DefaultObjectWrapper(<em class="code-color">...</em>)</code> + and <code class="inline-code">new + BeansWrapper(<em class="code-color">...</em>)</code>, from + now on you should use <code class="inline-code">new + DefaultObjectWrapperBuilder(version).build()</code> and + <code class="inline-code">new BeansWrapperBuilder(version).build()</code>. + (The builder objects have properties (configuration + settings) like <code class="inline-code">BeansWrapper</code> has, which + specify the properties of the objects created.) The created + objects are <em>singletons</em> (VM-wide, or at + least Web-Application-wide) and read-only (means, + non-configurable, hence safe to share). The main benefit of + using these factories instead of creating new instances is + that it allows FreeMarker to share the class introspection + caches (an internal part of + <code class="inline-code">BeansWrapper</code>-s/<code class="inline-code">DefaultObjectWrapper</code>-s + that is expensive to populate) among the returned instances. + This allow sharing the caches (and the object wrappers) + between components that aren't aware of each other and use + FreeMarker internally.</p> + </li> + + <li> + <p>Deprecated the static fields + <code class="inline-code">ObjectWrapper.DEFAULT_WRAPPER</code>, + <code class="inline-code">BEANS_WRAPPER</code> and + <code class="inline-code">SIMPLE_WRAPPER</code>, because these + <code class="inline-code">ObjectWrapper</code>-s are configurable (not + read-only), and thus dangerous to use as singletons (a badly + behaving 3rd party component can mess them up). Use the + factories described above instead. They are also more + flexible, as you can specify the desired + incompatible-improvements version for them and various other + <code class="inline-code">BeansWrapper</code> settings.</p> + </li> + + <li> + <p>Deprecated all <code class="inline-code">SimpleHash</code>, + <code class="inline-code">SimpleCollection</code> and + <code class="inline-code">SimpleSequence</code> constructors that didn't + take an <code class="inline-code">ObjectWrapper</code> argument, as they + have usually used + <code class="inline-code">ObjectWrapper.DEFAULT_WRAPPER</code> as the + default, which itself is deprecated.</p> + </li> + + <li> + <p><code class="inline-code">BeansWrapper</code>, + <code class="inline-code">DefaultObjectWrapper</code> and + <code class="inline-code">SimpleObjectWrapper</code> now implements the + <code class="inline-code">freemarker.template.utility.WriteProtectable</code> + interface with which the configuration properties of the + object wrapper can be set permanently to read-only by + calling <code class="inline-code">writeProtect()</code>. An attempt to + call a setter on a such <code class="inline-code">ObjectWrapper</code> + will immediately cause + <code class="inline-code">IllegalStateException</code>. (This is what's + used for the singletons returned by the + <code class="inline-code">getInstance</code> methods too; see + earlier).</p> + </li> + </ul> + </li> + + <li> + <p>The value of the <code class="inline-code">time_zone</code> setting, + when you specify it with a <code class="inline-code">String</code> (in a + <code class="inline-code">java.util.Properties</code> object, or via + <code class="inline-code"><#setting + <em class="code-color">...</em>></code>) can now be + <code class="inline-code">"JVM default"</code> to use the JVM default time + zone. The JVM default is the default value of that setting + anyway, but now you can state this explicitly, or restore this + value if it was overridden earlier.</p> + </li> + + <li> + <p>Added new configuration setting, + <code class="inline-code">sql_date_and_time_time_zone</code> + (<code class="inline-code">Configurable.setSQLDateAndTimeTimeZone(TimeZone)</code>). + When this is set to non-<code class="inline-code">null</code>, the time zone + used when dealing with <code class="inline-code">java.sql.Date</code> and + <code class="inline-code">java.sql.Time</code> values will be this time zone + instead of the value of the <code class="inline-code">time_zone</code> + FreeMarker configuration setting. This is useful because JDBC + will, usually, construct the Java <code class="inline-code">Date</code> + objects so that they will show the year-month-day and + hour-minute-seconds values from the database "as + is" if you render them using the JVM default time zone. + As time zone conversions for SQL date-only and SQL time-only + values doesn't make much sense (unlike for SQL timestamps), you + should certainly set this setting to the JVM default time zone + (<code class="inline-code">TimeZone.getDefault()</code>, or if you configure + FreeMarker via <code class="inline-code">java.util.Properties</code>, as + property value "JVM default"). The default value is + <code class="inline-code">null</code> for backward compatibility. For more + details see the JavaDoc of + <code class="inline-code">Configurable.setSQLDateAndTimeTimeZone(TimeZone)</code>.</p> + </li> + + <li> + <p>When configuring FreeMarker with + <code class="inline-code">java.util.Properties</code> (typically, when the + configuration is stored in a <code class="inline-code">.properties</code> + file), for the settings where you could specify a fully + qualified class name (most notably for the + <code class="inline-code">object_wrapper</code> setting) now you can also + specify constructor arguments and JavaBean property assignments. + For example, now you can write + <code class="inline-code">object_wrapper=com.example.MyObjectWrapper(1, 2, + exposeFields=true, cacheSize=5000)</code>that's nearly + equivalent with this Java code: <code class="inline-code">obj = new + com.example.MyObjectWrapper(1, 2); obj.setExposeFields(true); + obj.setCacheSize(5000); object_wrapper = obj;</code>. If you + are using this new syntax (i.e., if you have parentheses after + the class name, even if they are empty), and there's a builder + class for the requested class, that will be automatically used. + For example, + <code class="inline-code">object_wrapper=DefaultObjectWrapper(2.3.21)</code> + will create a <code class="inline-code">DefaultObjectWrapperBuilder</code> to + build the final instance, thus the object wrapper will be a + singleton instead of a new instance. The new syntax will also + look for a public static <code class="inline-code">INSTANCE</code> field if + there are 0 arguments and property assignments. For more details + see the Java API documentation of + <code class="inline-code">Configuration.setSetting</code>.</p> + </li> + + <li> + <p>Template not found exceptions now explain that the + template path is interpreted by a template loader, and show the + <code class="inline-code">toString</code> of the + <code class="inline-code">TemplateLoader</code>. The out-of-the-box + <code class="inline-code">TemplateLoader</code> implementations now have an + overridden <code class="inline-code">toString</code> to show the actual base + directory and such details. Custom + <code class="inline-code">TemplateLoader</code> implementations are encouraged + to override <code class="inline-code">toString</code>.</p> + </li> + + <li> + <p>Added + <code class="inline-code">Configuration.setSharedVariables(Map/*<String, + Object>*/)</code> for setting the shared variables from + Spring IoC and other IoC solutions. The already existing + <code class="inline-code">Configuration.setSharedVariable(String, + Object)</code> isn't a JavaBean property so it was hard to + use for that. Furthermore, the order in which + <code class="inline-code">Configuration.setObjectWrapper</code> and + <code class="inline-code">Configuration.setSharedVariables</code> are called + doesn't mater (unlike in the case of + <code class="inline-code">Configuration.setSharedVariable</code>), which is + essential in most IoC solutions.</p> + </li> + + <li> + <p>Mostly concerning tool (like IDE plugin) authors:</p> + + <ul> + <li> + <p><code class="inline-code">ParseException</code>-s now also store the + end-location of the error, not just its start-location. This + is useful if you want to underline the error in the source + code, not just point at it.</p> + </li> + + <li> + <p><code class="inline-code">Configuration.getSupportedBuiltInDirectiveNames()</code> + can be used to return the names of directives supported by + FreeMarker.</p> + </li> + + <li> + <p><code class="inline-code">TemplateExceptions</code> now expose the + position of the error (template name, line, column, end + line, end column) similarly to + <code class="inline-code">ParseException</code>-s. Where applicable, they + also expose the blamed expression in its canonical FTL + source form; this is mostly useful for + <code class="inline-code">InvalidReferenceException</code>-s.</p> + </li> + </ul> + </li> + + <li> + <p>The concurrent performance of overloaded method lookups + (from the cache) was improved under Java 5 and later.</p> + </li> + + <li> + <p>The <code class="inline-code">Version</code> instances that are + "incompatible improvements" break points are now + available via constants like: + <code class="inline-code">Configuration.VERSION_2_3_21</code>.</p> + </li> + + <li> + <p>From now on, if you try to set the "incompatible + improvements" to greater than the current FreeMarker + version, or less than 2.3.0, an + <code class="inline-code">IllegalArgumentException</code> will be thrown. + Thus, <code class="inline-code">new + Configuration(<em class="code-color">someVersion</em>)</code> + not only activates the fixes up to that version, but ensures + that the application will not run in an environment with an + older FreeMarker version. (On an older FreeMarker version the + improvements that you have requested aren't implemented yet, so + you should get an exception.)</p> + </li> + + <li> + <p>Added new configuration setting, + <code class="inline-code">show_error_tips</code>, defaults to + <code class="inline-code">true</code>. Sets if tips should be shown in error + messages of errors arising during template processing.</p> + </li> + + <li> + <p>Instead of overriding + <code class="inline-code">BeansWrapper.finetuneMethodAppearance</code> (now + deprecated), now you can use + <code class="inline-code">BeansWrapper.setMethodAppearanceFineTuner(MethodAppearanceFineTuner)</code>, + so you don't need to extend the object wrapper class to + customize this aspect.</p> + </li> + + <li> + <p>Added + <code class="inline-code">Configuration.getCoreDirecticeNames()</code> which + returns the names of all directives that are provided by + FreeMarker. This can useful for IDE-s.</p> + </li> + + <li> + <p><code class="inline-code">template_loader</code> was added as possible + configuration setting <code class="inline-code">Properties</code> key.</p> + </li> + + <li> + <p>The standard <code class="inline-code">CacheStorage</code> + implementations now have a <code class="inline-code">getSize()</code> method + for monitoring the cache size. + <code class="inline-code">MruCacheStorage</code> also has + <code class="inline-code">getSoftSize()</code> and + <code class="inline-code">getStrongSize()</code>.</p> + </li> + + <li> + <p>Various smaller improvements in configuration setting + errors messages.</p> + </li> + + <li> + <p>With incompatible improvements 2.3.21 only: Empty ranges + return <code class="inline-code">Constants.EMPTY_SEQUENCE</code> instead of an + empty <code class="inline-code">SimpleSequence</code>. This is in theory + backward compatible, as the API only promises to give something + that implements <code class="inline-code">TemplateSequenceModel</code>.</p> + </li> + + <li> + <p>FreeMarker now requires Java version has changed from 1.2 + to 1.4.</p> + </li> + + <li> + <p>Bugs fixed and improvements in overloaded method + selection/invocation, but only if you create the + <code class="inline-code">BeansWrapper</code>/<code class="inline-code">DefaultObjectWrapper</code> + with constructor parameter + <code class="inline-code">Configuration.VERSION_2_3_21</code> (or if you are + using <code class="inline-code">Properties</code> to configure FreeMarker, you + can do that like + <code class="inline-code">object_wrapper=BeansWrapper(2.3.21)</code>), or if + you have a <code class="inline-code">Configuration</code> with similar + <code class="inline-code">incompatible_improvements</code> 2.3.21 + <em>and</em> you leave the + <code class="inline-code">object_wrapper</code> setting on its default value. + There's a little chance that because of these changes, a + different overloaded method will be chosen than before, or even + that ambiguity errors will arise where earlier they didn't + (although the opposite is far more frequent), hence the fixes + aren't automatically activated. But the fix mostly only effect + calls that were failing or have chosen then wrong method + earlier, so it's recommended to activate it for projects that + are still actively developed. This fix includes numerous + changes:</p> + + <ul> + <li> + <p>Earlier, <code class="inline-code">null</code> argument values has + only matched overloaded methods where the corresponding + parameter had <code class="inline-code">Object</code> type, not a subclass + of it. That's clearly a bug. Now it considers all overloads + where the parameter type is non-primitive, and just like the + Java language, it choses the one with the most specific type + among them. This is the most important fix, and also the + most risky one regarding backward-compatibility. Like if you + have <code class="inline-code">m(Object o)</code> and <code class="inline-code">m(String + s)</code> in a Java class, earlier for a + <code class="inline-code">m(null)</code> call in the template it has + chosen <code class="inline-code">m(Object o)</code>, but now it will + choose <code class="inline-code">m(String s)</code> instead (because + <code class="inline-code">String</code> is also + <code class="inline-code">null</code>-able and is more specific than + <code class="inline-code">Object</code>). Furthermore, if you also had + <code class="inline-code">m(File f)</code> in the same class, now it will + cause an ambiguity exception, since the specificity of + <code class="inline-code">File</code> and <code class="inline-code">String</code> can't + be compared (same rule as under Java language), while + earlier that wasn't a problem as only <code class="inline-code">m(Object + o)</code> was seen as applicable.</p> + </li> + + <li> + <p>The behavior of numbers with overloaded method + selection was heavily reworked:</p> + + <ul> + <li> + <p>If possible, it now always choses the overload + where overflow and truncation to integer (like 1.5 to 1) + is avoided. Among the methods where no such critical + loss occurs, it choses the overload with the least risk + of precision loss (unless other conditions with higher + priority suggest otherwise). Earlier, the method + selection was prone to do choices that led to overflow + or precision loss, especially when the parameter was a + literal with decimals.</p> + </li> + + <li> + <p>Overloaded method call can now convert to + non-primitive numerical types, like a + <code class="inline-code">Byte</code> or <code class="inline-code">byte</code> value + is automatically converted to <code class="inline-code">Integer</code> + if the parameter type is <code class="inline-code">Integer</code>. + (This has always worked for non-overloaded methods.) + Earlier where such conversion was needed, the method + wasn't seen seen applicable.</p> + </li> + + <li> + <p>Method selection is now not only based on the type + of the wrapped number, but also on its value. For + example, a <code class="inline-code">Long</code> with value + <code class="inline-code">1</code> is now seen as compatible with a + method with parameter type <code class="inline-code">int</code> or + <code class="inline-code">short</code> or <code class="inline-code">byte</code>, as + <code class="inline-code">1</code> can be stored in those without + loss. This is important as unlike in Java language, in + FTL you doesn't have strict control over the numerical + types (the type of the wrapped number, actually), as FTL + has no type declarations. (If multiple compatible + methods are available, it will still try to chose the + one with the same or bigger numerical type.)</p> + </li> + + <li> + <p>Conversion from/to <code class="inline-code">BigInteger</code> + is now supported.</p> + </li> + </ul> + </li> + + <li> + <p>Method choice ambiguity errors now occur much less + often. Ambiguities was and are resolved by selecting the + compatible methods then choosing the one with the most + specific parameter types among them. The changes are:</p> + + <ul> + <li> + <p>When comparing the overall specificity of two + parameter lists: Earlier the parameter list seen as more + specific was the one that had some parameters that won + in specificity, and if both had such parameters then it + was an ambiguity. Now it's enough if a method has more + such parameters where it's a better match than the other + has, or if the two methods are still equal, if it has + the first better matching parameter. This can lead to + choices that seem arbitrary (but are still + deterministic), but as there's no automated way of + discovering method selection ambiguities in templates + (unlike in Java source code, where they will be detected + during compilation), especially as overloaded selection + has to rely on the <em>runtime</em> type of + the values which even make proper testing hard, this was + considered to be a better compromise than throwing an + exception whenever the choice of the method is not + obvious. Also note that in fact this mechanism is more + complicated than just counting the "winner" + parameter positions for each methods, as certain kind of + wins are stronger than any number of the others: wins + where the other possibility is risking of substantial + mantissa precision loss are the strongest (like dropping + decimals versus not to), wins where the primitive type + wins over the boxed class is the weakest (like + <code class="inline-code">int</code> versus + <code class="inline-code">Integer</code>), subclassing wins (like + <code class="inline-code">String</code> versus + <code class="inline-code">Object</code>) are between these two.</p> + </li> + + <li> + <p>When comparing the specificity of two parameters + types at the same parameter position: The algorithm now + considers a primitive type as more specific that its + corresponding boxing class (like <code class="inline-code">int</code> + is considered to be more specific than + <code class="inline-code">Integer</code>).</p> + </li> + + <li> + <p>There was a bug with overloaded varargs methods of + different parameter counts, where sometimes the last + parameters of the compared methods was ignored, which is + taking away a potential deciding factor and thus can + lead to ambiguity error. Whether this happened depends + on the order in which the Java reflection API has + returned the methods, which is undocumented and known to + change at least after some Java updates, breaking the + application.</p> + </li> + + <li> + <p>When comparing the specificity of two array types, + until now they were seen as equal. Now the component + types are compared, and then that with the less specific + component type is preferred. For example, among + <code class="inline-code">f(String[])</code> and + <code class="inline-code">f(Object[])</code>, the last will always + win. This might sounds controversial, but as we can't + efficiently tell the common type of all the items in a + sequence or <code class="inline-code">List</code>, an so we don't know + if both arrays are indeed valid targets, we go for the + safest choice.</p> + </li> + </ul> + </li> + + <li> + <p>FTL sequence values (like Java + <code class="inline-code">List</code>-s or FTL + <code class="inline-code">[<em class="code-color">x</em>, + <em class="code-color">y</em>, + <em class="code-color">...</em>]</code> constants) were + not seen as applicable to a parameter with array type if + there were multiple overloaded methods with the same number + of parameters but with different types on the position of + the array parameter. That is, if you had + <code class="inline-code">f(String[])</code> and + <code class="inline-code">f(String)</code> in Java, then + <code class="inline-code">f(['foo', 'bar'])</code> in the template + reported no compatible overloads. Now it will choose + <code class="inline-code">f(String[])</code>. Note that if there's also an + <code class="inline-code">f(List)</code> or even an + <code class="inline-code">f(Collection)</code>, it will prefer those over + arrays. (For consistency, this conversion will work even if + the argument is a <code class="inline-code">List</code> that come directly + from Java (as opposed to be created inside FTL), i.e., when + it was wrapped then unwrapped to the original + <code class="inline-code">List</code> object.) For a multidimensional + array parameter type, this conversion works recursively, so + you can pass in a sequence-of-sequences as the + argument.</p> + </li> + + <li> + <p>FTL sequence values that wrapped a Java array (when + FreeMarker was also aware of that via + <code class="inline-code">AdapterTemplateModel</code> or + <code class="inline-code">WrapperTemplateModel</code>) were not seen as + applicable to a parameter with <code class="inline-code">List</code> type + if there were multiple overloaded methods with the same + number of parameters but with different types on the + position of the array parameter. So this is pretty much like + the issue described in the previous point, but for array to + <code class="inline-code">List</code> conversion. The array to + <code class="inline-code">List</code> conversion will be avoided if + possible, but it will be attempted if there's no other + alternative. Note that unlike with <code class="inline-code">List</code> + to array conversions, here FreeMarker can't cope with + multi-dimensional lists, that is, an array-of-arrays won't + be converted to a + <code class="inline-code">List</code>-of-<code class="inline-code">List</code>-s.</p> + </li> + + <li> + <p>FTL string to Java + <code class="inline-code">char</code>/<code class="inline-code">Character</code> + conversion now works for overloaded method parameters; + earlier it has worked for non-overloaded methods only. If + the string length is 1, it will be seen as compatible with + parameters with <code class="inline-code">char</code> or + <code class="inline-code">Character</code> type.</p> + </li> + + <li> + <p>Decreased the chance of choosing the wrong target Java + type when unwrapping multi-typed FTL values: When unwrapping + a parameter value that implements multiple FTL types (e.g. + string and hash) but doesn't implement + <code class="inline-code">AdapterTemplateModel</code> or + <code class="inline-code">WrapperTemplateModel</code>, a decision has to + be made if to what Java type the value should be unwrapped + to (e.g. to <code class="inline-code">String</code> or to + <code class="inline-code">Map</code>). In earlier versions that decision + was made based on the most specific common super type of the + parameters types of the given parameter position. However, + it's quite common that the common super type is too generic, + usually <code class="inline-code">Object</code>. Now + <code class="inline-code">BeansWrapper</code> stores "type + flags" for each parameter position of overloaded + methods, from which it can tell whether a potential target + Java type occurs in any of the overloads on the given + parameter position.</p> + </li> + + <li> + <p>In many cases, less specific hint class was used for + unwrapping than that was possible within the limitations of + the applied hint generation algorithm. (The unwrapping hint + has influence when there's an ambiguity regarding how to + create a Java object form an FTL value. In the vast majority + of the cases, a too generic hint has no effect.) (This is a + highly technical topic. The way it works is that a single + common unwrapping hint class is chosen for a given argument + position shared by the overloads that has the same number of + parameters, and that hint class has to be as specific as + possible while it must fit all those parameter types. The + issue with the too generic hints had several instances: (a) + When the most specific common class/interface of two + same-position parameter types was searched, if there was + multiple common classes/interfaces that had no relationship + (this is always at most one class and one or more unrelated + interfaces), due to the ambiguity it has felt back to using + <code class="inline-code">Object</code> as the unwrapping hint. Now if + there's a non-<code class="inline-code">Object</code> class among them in + such case, it will be chosen as the hint (i.e., we ignore + the common interfaces). Otherwise if only a single interface + remains by removing <code class="inline-code">Cloneable</code>, + <code class="inline-code">Serializable</code>, and + <code class="inline-code">Comparable</code> (in that order), that will be + chosen. Only then it falls back to + <code class="inline-code">Object</code>. (b) The common most specific + class of a primitive type and the corresponding boxing class + was sometimes <code class="inline-code">Object</code> instead of the + boxing class. This has depended on Java's internal ordering + of the methods, and so were quite unpredictable, like the + result could change after upgrading Java under the + application. (c) The common superclass of a numerical + primitive value and a numerical non-primitive value was + always <code class="inline-code">Object</code>, now if they are a + primitive-boxing class pair, then it's the boxing class, + otherwise it's <code class="inline-code">Number</code>. (d) If the varags + parameter position was not the same in all the overloaded + varargs methods, sometimes some varargs arguments where + unwrapped with too generic hints. When this happened was + unpredictable as it depended on Java's internal method + ordering again.)</p> + </li> + + <li> + <p>When unwrapping method call arguments before calling a + Java method, if the argument was an + <code class="inline-code">AdapterTemplateModel</code> and the target + parameter type was primitive, + <code class="inline-code">AdapterTemplateModel.getAdaptedObject(Class + hint)</code> has received the primitive type of the + target parameter (like <code class="inline-code">int</code> instead of + <code class="inline-code">Integer</code>) as the hint. This did not make + sense since <code class="inline-code">getAdaptedObject</code> can only + return <code class="inline-code">Object</code>-s, not primitive values. + Yet, <code class="inline-code">BeansWrapper</code> has expected the + returned value to be of the primitive type, otherwise it has + discarded it. Exactly the same problem occurs with + <code class="inline-code">WrapperTemplateModel</code>. Thus, ultimately, + if the target parameter type was primitive and some of these + interfaces were implemented, their return value was always + discarded and FreeMarker has felt back to other means of + unwrapping. Now <code class="inline-code">BeansWrapper</code> always + passes in and expects the boxing type (like + <code class="inline-code">Integer</code>) instead of the primitive + type.</p> + </li> + </ul> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/373/">373</a>]: + These are three bugs actually, which can cause problems when + FreeMarker re-loads a template because of a charset override + with <code class="inline-code"><#ftl encoding="..."></code>: First, if + the template loader was a <code class="inline-code">URLTemplateLoader</code>, + when <code class="inline-code">TemplateLoader.getReader()</code> was called + for the second time, and the <code class="inline-code">Reader</code> returned + for the first time was already used, it might returned an empty + or corrupted template, depending on the backing URL + implementation. Secondly, when FreeMarer has decided if a + template file has to be re-loaded because its encoding specified + with <code class="inline-code"><#ftl encoding="..."></code> differs from + the encoding used for loading the template first, it has used + case-sensitive comparison, thus often re-loaded needlessly (like + "UTF-8" and "utf-8" mean the same). Now this comparison is + case-insensitive. Last not least, when retrying with the second + charset, the <code class="inline-code">TemplateCache</code> has forgotten to + close the first <code class="inline-code">Reader</code>, which can be a handle + leak.</p> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/411/">411</a>]: + Invalid and redundant execution environment names from the OSGi + bundle manifest were removed. It looks like this now: + <code class="inline-code">Bundle-RequiredExecutionEnvironment: J2SE-1.5, + J2SE-1.4</code>. That is, we prefer (and compile against) + 1.5, but only require 1.4.</p> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/409/">409</a>]: + <code class="inline-code">SimpleHash</code>'s internal <code class="inline-code">Map</code> + is concurrently modified on a non-safe way when getting length-1 + <code class="inline-code">String</code> key that exists but maps to + <code class="inline-code">null</code>. This operation will accidentally add a + <code class="inline-code">Character</code> key to the internal map, which is + not a thread-safe operation.</p> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/273/">273</a>]: + <code class="inline-code">TemplateLoader</code>-s that use + <code class="inline-code">java.net.URLConnection</code>-s should set + <code class="inline-code">URLConnection.useCaches</code> to + <code class="inline-code">false</code>, or else it won't detect template + caches on certain configurations.</p> + + <ul> + <li> + <p><code class="inline-code">URLTemplateLoader</code> and its + subclasses and + <code class="inline-code">WebApplicationTemplateLoader</code> now has a + <code class="inline-code">setURLConnectionUsesCaches(Boolean)</code> + method. It's recommended to set this property to + <code class="inline-code">false</code> from its default backward + compatible value, <code class="inline-code">null</code>. As FreeMarker has + its own template cache with its own update delay setting + (<code class="inline-code">template_update_delay</code>, + <code class="inline-code">Configuration.setTemplateUpdateDelay(int)</code>), + it shouldn't cause performance problems. The + <code class="inline-code">null</code> value will leave the caching of the + <code class="inline-code">java.net.URLConnection</code> on its default, + which is usually <code class="inline-code">true</code>.</p> + </li> + + <li> + <p>If <code class="inline-code">incompatible_improvements</code> is set + to 2.3.21 (or higher) and templates are loaded through + <code class="inline-code">Configuration.getTemplate</code>, and the + <code class="inline-code">TemplateLoader</code> in use has + <code class="inline-code">URLConnectionUsesCaches</code> left on + <code class="inline-code">null</code>, it will behave as if it was set to + <code class="inline-code">false</code>. Note that this + <code class="inline-code">incompatible_improvements</code> trick only + works if the template is loaded through + <code class="inline-code">Configuration.getTemplate</code> (or + <code class="inline-code">TemplateCache</code>).</p> + </li> + </ul> + </li> + + <li> + <p>Bug fixed: When changing the properties of + <code class="inline-code">DefaultObjectWrapper</code> or + <code class="inline-code">BeansWrapper</code> that influenced class + introspection results (like <code class="inline-code">exposureLevel</code> or + <code class="inline-code">exposeFields</code>), the introspection cache wasn't + cleared, and thus returned stale information for the classes + that were introspected before those properties were changed. Now + changing such properties always clears the introspection + caches.</p> + </li> + + <li> + <p>Bug fixed: Constants used for empty sequence, empty hash, + empty collection and empty iterator weren't + <code class="inline-code">Serializable</code>.</p> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/311/">300</a>]: + Logger class availability check was incorrect in that it has + checked the availability of logger libraries with the thread + context class loader, then later it tried to link to them with + the defining class loader of the FreeMarker classes. With some + class loader setups (notably under Netbeans sometimes) this led + to <code class="inline-code">ClassDefNotFoundError</code>-s that made + FreeMarker unusable. (The check itself was also not very + durable, as it didn't expected <code class="inline-code">LinakeError</code>-s, + only <code class="inline-code">ClassNotFoundException</code>.)</p> + </li> + + <li> + <p>Bug fixed: <code class="inline-code">ClassUtil.forName</code>, used + inside FreeMarker everywhere to resolve class names to classes, + if the thread context class loader is <code class="inline-code">null</code>, + no longer tries to load with the bootstrap class loader before + loading with the defining class loader of FreeMarker.</p> + </li> + + <li> + <p>Bug fixed [<a href="http://sourceforge.net/p/freemarker/bugs/311/">311</a>]: + <code class="inline-code">TemplateBooleanModel.TRUE</code> and + <code class="inline-code">FALSE</code> are now serializable</p> + </li> + + <li> + <p>Bug fixed: Various issues in <code class="inline-code">Version</code> + class, such as wrong <code class="inline-code">hashCode</code>, possible + concurrency glitches, and acceptance of some malformed version + strings.</p> + </li> + + <li> + <p>Bug fixed [<a href="https://sourceforge.net/p/freemarker/bugs/414/">414</a>]: + Eclipse debug mode running was suspended during FreeMarker + static initialization on the JRebel availability checked if + JRebel wasn't available.</p> + </li> + </ul> + + + + + +<h2 class="content-header header-section2" id="autoid_173">Other changes</h2> + + + <ul> + <li> + <p>The license has changed from our proprietary BSD-Style + license to the well know "Apache License, Version 2.0". + Furthermore, the copyright owner has changed from "Visigoth + Software Society" (which was founded by Jonathan Revusky) to the + three main FreeMarker 2 developers/contributors, "Attila + Szegedi, Daniel Dekany, and Jonathan Revusky". See the <a href="app_license.html">new license here</a>.</p> + </li> + + <li> + <p>The required minimum Java version was raised from 1.2 to + 1.4. FreeMarker will not work on Java 1.2 or 1.3.</p> + </li> + + <li> + <p>Many smaller improvements and fixes in the Manual and API + JavaDocs.</p> + </li> + </ul> + <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_3_22.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_20.html"><span>Next</span></a></div></div></div></div> </div> + </div> +<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="http://freemarker.org/">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href ="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://issues.apache.org/jira/browse/FREEMARKER/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated"> +Last generated: +<time itemprop="dateModified" datetime="2017-03-13T10:55:28Z" title="Monday, March 13, 2017 10:55:28 AM GMT">2017-03-13 10:55:28 GMT</time>, for Freemarker 2.3.26 <
<TRUNCATED>
