http://git-wip-us.apache.org/repos/asf/incubator-freemarker-site/blob/a4004324/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 deleted file mode 100644 index 6740ac9..0000000 --- a/builds/2.3.26-nightly/versions_2_3_21.html +++ /dev/null @@ -1,1419 +0,0 @@ -<!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.
<TRUNCATED>
