You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/03/13 10:57:43 UTC
[07/50] incubator-freemarker-site git commit: 2.3.26-nightly docs
preview
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>