FM-Classic 1.9 Beta 2 README

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

Click here for the manual.

Click here for javadoc-generated documentation.

Click here for notes on the source code.

Note: the classes in freemarker.jar have been compiled with the -O option of javac. They contain only source file debugging information. Before submitting a bug report, please recompile FM-Classic with full debugging information, so you can submit a complete stack trace of any exceptions thrown.

Authors: Benjamin Geer and Mike Bayer

Updates can be found at

Version history:

Version Date Changes
1.9B2 27 April 2013
  • Added the freemarker.engine package. This ties together the template system, the cache, and the reflection code to present a unified API to all these services.
  • Added a <local> instruction block. This allows variables within the block to be visible only inside the block.
  • Lambda expressions can be created using the #lambda expression. When combined with <function> or <local> instructions, can be used to capture scope.
  • Created factory classes for various classes around the system. For instance, TemplateFactory creates Template objects. These help FMEngine configuration.
  • Variable expressions can be escaped on output. For instance, you can HTML-encode any variables written to the output. Individual variable output can be left unescaped optionally using the ${variable unescaped} instruction.
1.9B1 16 October 2005
  • Added new writeable models: writeable hashes, writeable indexed models, and writeable iterators.
  • Created a new reflection library that takes advantage of the new writeable models.
  • Added a format package for simple message, number, and date formatting capabilities.
  • The <assign> instruction can be a standalone or a block element.
  • See the changelog for all the details...
1.8.5 16 November 2004
  • Provided a Java 5.0 build in addition to a Java 1.2 build. The Java 5.0 source code takes advantage of new language features and improves type safety within the engine.
  • Streamlined the expression builder to use an O(n2) algorithm instead of O(n3) when determining operator precedence.
  • Serialized forms of Java 1.2 and Java 5.0 templates and models should be interchangeable. Most of the freemarker.ext models are now serializable.
  • Constant list and hash literals are now evaluated at compile time instead of having to be calculated at runtime.
  • A simple expression cache has been added to reduce in-memory template size. In low memory conditions the cache will automatically reclaim any expressions that are no longer required.
1.8.2 6 October 2004
  • Added several Perl work-a-like methods to the freemarker.ext.misc package using the Jakarta ORO library.
  • Template functions can now return early using the <exit> instruction.
  • Fixed several scenarios where the <break> instruction didn't work as expected.
  • Updated JDom support to JDom beta 10 and JDom 1.0. This breaks compatibility with older versions of JDom.
  • Minor fix to the JDom _descendant navigator to correctly return the root element of a document when starting from a Document node. This mimics standard XPath behaviour.
  • Parameterised the Ant scripts so that external libraries can be configured from a file.
  • Introduced freemarker.ext.misc.WriterExceptionListener for intercepting FM-Classic events and sending them to a Writer. This is useful when sending messages to System.err without the need for Log4J.
  • Implemented better logging information for the <freemarker> Ant task. Diagnostic information now goes to the Ant log rather than the template output.
1.8.1 18 February 2004
  • The JDom NodeListModel class now implements TemplateObjectModel. This makes it possible to determine the number of nodes in a node list.
  • Created Transforms and Methods classes in the freemarker.ext.misc package. These provide a convenient way to access all method and transform models within that package.
  • Transforms and Methods classes used in the freemarker.ext.jdom and freemarker.ext.ant packages.
  • The break instruction has been modified so that it can be nested arbitrarily deeply within a case or default statement. The break instruction can also be used within a list or foreach instruction.
1.8 6 December 2003 Minor JavaDoc fixes, updates to the Manual, and toString corrections.
1.8RC2 27 November 2003
  • Now more pedantic about testing the isEmpty method before evaluating variables, methods, lists, and transforms. Previously, we didn't use it in many cases. Made some clarifications to the manual as a result.
  • Added method models to freemarker.ext.misc to retrieve keysets and values from a Map, and the size of a Collection or Map. These use the TemplateObjectModel interface to retrieve the underlying Collection or Map. See CollectionSize, HashKeys, and HashValues.
  • Implemented toString method in many classes, so that calling it on a Template object will give an overview of the parse tree.
1.8RC1 16 November 2003
  • Added a new template caching policy to FileTemplateCache. Added ability to expire templates from a FileTemplateCache for certain caching policies. Updated the FreeMarkerServlet class to use the new caching policy.
  • Templates can now be serialized, although in practise it is better to recompile a template from scratch where possible, due to the fact that a serialized template ends up much larger than its original text format.
  • Many constant expressions are now evaluated at compile time rather than run time. This simplifies the expression tree, and avoids runtime overhead in re-evaluating constants each time a template is processed.
  • Added a Perl 5 transformation model to the freemarker.ext.misc package. One or more Perl 5 substitutions can be passed in, and are evaluated in turn on a line-per-line basis on the data.
  • Added method models to freemarker.ext.misc to allow testing of model capabilities from within a template. See IsScalar, IsNumber, IsHash, etc.
  • Build against current versions of Jakarta ORO, Apache Ant, Log4j.
1.7.6 13 November 2003

This is a maintenance release to 1.7.5.

  • Fixed a null pointer exception in ExpressionUtils.
  • Allow parenthesis around variable in a switch statement. Apparently, ancient versions of FreeMarker allowed this (circa 1.3).
  • Slight code optimization in evaluation of switch statements at runtime.
1.8B1 3 November 2003
  • Introduced TemplateNumberModel and FastNumber, which use the Java long type (64-bit integer) to hold numeric values.
  • Introduced TemplateMethodModel2 to allow any TemplateModel to be pass as a parameter into a method call. This is particularly useful with the introduction of TemplateNumberModel.
  • Introduced TemplateListModel2, TemplateIteratorModel, and TemplateIndexedModel. These take over from the now deprecated TemplateListModel.
  • TemplateIteratorModel can be accessed from within a list or foreach instruction using the index# notation.
  • With the cementing of TemplateNumberModel as an integer type, no longer accept decimal points in a number literal. (The parser would accept them in previous releases.)
  • Added elseif tag. The number of elseif tags allowed is unbounded.
  • Added numeric comparison operators, such as lessthan, greaterthan, and so on. For regularity, also added text versions of the equals, notequals, and, and or operators. Re-jigged the parser to avoid confusion with regular variable names.
  • The semicolon in the include instruction is now optional
  • Implemented simple list ranges.
  • Reworked parts of the freemarker.ext.beans package to use the new template models. This gives us a few useful optimizations. Also added simple test cases for this package.
  • Method calls and function calls are now interchangeable. Wherever a function call can be made, a method call can also be made, and vice versa. Some minor inefficiencies are introduced when performing function calls from a non-call instruction, since the output has to be buffered.
  • Functions now always occupy the same namespace as all other template models. Previously, there were funky exceptions to this depending on whether include instructions were used.
  • Verified the freemarker.ext.jdom package works correctly with JDom beta 9. Verified the examples continue to work.
  • Removed the compress instruction from the library, following the deprecation in 1.7.5. The compress transformers in the freemarker.ext.misc package provide replacement functionality.
  • Created TemplateObjectModel and implemented it in the non-trivial Simple and Fast models. Provides support functionality to the freemarker.ext.beans package.
  • Added TemplateTransformModel2 which has an output of Writer instead of PrintWriter. Many of the transformer classes in the freemarker.ext.misc package now implement this instead of TemplateTransformModel. Both interfaces can now throw IOException as well as TemplateModelException.
  • Removed a lot of methods and classes that were deprecated in previous releases.
  June 2002 Renamed the project to FM-Classic, to avoid any confusion with the FreeMarker project.
1.7.5 1 June 2002
  • Reworked expression handling to use less inheritance and handle string and boolean tests more generically. Regularised the handling of booleans and list/hash literals as a side effect.
  • Exception classes enhanced. TemplateModelException is now a subclass of TemplateException. New ParseException class (also subclass of TemplateException) introduced for handling exceptions during template compilation.
  • All exception classes can also take an Exception parameter to indicate the cause of the exception. Reworked parts of the expression and intruction code to take advantage of this. Also enhanced the HtmlExceptionListener to use it when available.
  • Added Fast models. These are fast-and-furious versions of the Simple models. These models don't use any synchronization at all, avoiding the runtime cost of stepping in and out of synchronization locks.
  • FastBoolean now uses a factory method to generate instances. This avoids the cost of creating new objects for each boolean instance we're after.
  • The Expose package has been merged with the main FreeMarker tree. The Expose classes can be found in the freemarker.ext package.
  • The freemarker.template.utility package has been moved to the freemarker.ext.misc package.
  • Many of the examples have been re-organised. This includes the introduction of a new Ant build file to build the examples.
  • Serialization tidied up to be compatible with the 1.7 release. The Fast models are now serializable, since they are used by the Simple models, which are themselves serializable.
  • Major additions to the JavaDoc. Now all the packages are JavaDocced. JavaDoc is now split into groups, for clarity.
  • Added a TODO file to the distribution.
  • ...
2.0 February 2002 The 2.0 code base (Lazarus) is based on the 1.7.1 release. Future work on the 1.x and 2.x codebases now continues separately.
1.7.1 16 January 2002
  • Add checks for <include> instructions that attempt to escape the cache root directory. Removes a potentially serious security vulnerability when using LOAD_ON_DEMAND or NULL_CACHE caching policies.
  • Minor fix to remove null pointer exceptions from FileRetriever and LocalizedFileRetriever when checking the cache root directory.
  • Other minor bug fixes.
1.7 3 November 2001
  • Added documentation of Template event listeners to the manual.
  • Added package-level documentation to the freemarker.doc package.
1.7RC1 19 October 2001
  • Cache refactoring to make caching more generic and pluggable.
  • Performance and memory optimizations in the parser, as a result of profiling.
  • Addition of "unparsed" templates, to allow explicitly unparsed content to be included inside a container template.
  • Introduced event listeners to allow template errors to be logged to logging utilities such as Log4j.
  • New additions to the utility package, including syntax colouring for Java and FreeMarker files, and basic numeric support.
  • FreeMarker manual is now generated using FreeMarker, with syntax colouring in all sample code.
  • Plus much more...
1.6.2 18 August 2001
  • Many new features in the Expose package. See the Expose README for details.
  • Templates now preserve existing newlines by default. Added a NormalizeNewlines transformer to the utility package to retain backward-compatibility.
  • Minor changes to the parser to factor variable parsing from parsing of other expressions.
1.6.1 20 June 2001

Fixed regression with chaining dynamic keys. This was introduced by the new list literal syntax.

1.6 16 June 2001

Bug fix for Solaris users: FreeMarker now explicitly closes file handles. Previously FreeMarker could cause the Sun Solaris JVM to run out of file handles under high load.

1.6RC1 3 June 2001

New additions:

  • Added ListLiteral and HashLiterals
  • Added TemplateTransformModel
  • Created freemarker.template.utility package and associated JAR file
  • Added <noparse> template instruction


  • Major additions to the manual, regeneration of the JavaDoc, and minor updates to the examples
  • Bug fix to <comment> template tag
  • Update of reflection package (now known as Expose)
  • New build targets for the Ant build file
  • Plus many other minor updates...
1.5.3 2 November 2000

a lot of fixes/additions:

  • improved template caching (thanks to Alex Petrushko)
  • added numerical index for lists
  • added NumberLiteral
  • added foreach synonym for list
  • new Ant build file
  • added comment tag
  • error message now show line numbers
1.5.2 2 November 1999

Fixed a parser bug introduced in 1.5. Better caching policy in FileTemplateCache; the change in 1.5.1 would have caused a memory leak with LOAD_ON_DEMAND if template files were deleted.

1.5.1 29 October 1999

Better support for different character encodings. FileTemplateCache synchronization is really fixed now.

1.5 23 October 1999

Holger Arendt has added support for method calls in expressions; methods implement a TemplateMethodModel interface. FileTemplateCache synchronization has been simplified.

1.4.9 17 October 1999

Fixed a synchronization bug in FileTemplateCache.

1.4.8 29 June 1999

Extra parentheses in expressions are now always ignored.

1.4.7 20 May 1999 Improved compiler architecture.

Updatable and UpdateTimer have been made public to help implementors of TemplateCaches.

The location of an expression containing a syntax error is now always reported with the error.

1.4.6 6 May 1999 FileTemplateCache now fails more gracefully if an I/O error makes it impossible to list the files in a directory.
1.4.5 5 May 1999 TemplateCache is now an interface, implemented by FileTemplateCache. By default, this implementation now loads templates as they are requested, instead of preloading all available templates; the latter behavior can be still selected at run time.
1.4.4 29 April 1999 Tweaked to prevent thread deadlocks when firing multicast events.
1.4.3 24 April 1999

Fixed a concurrency problem with switch-case statements.

Identifiers must now begin with a letter.

1.4.2 23 April 1999

If there's a compile-time error, the error message is now the only thing in the output.

Fixed a compile-time error-trapping bug introduced in version 1.4.1.

1.4.1 23 April 1999

Allowed underscores in identifiers.

Some compiler optimization.

Fixed a serialization problem with SimpleList.

Some small improvements in error reporting.

1.4 15 April 1999

Added dynamic hash keys (see "Variables" in the manual). This required changing the way variables are parsed; variable delimiters in tags are therefore no longer supported.

Added a string concatenation operator.

Added support for expressions in assignments, case statements, include statements, and function arguments.

Reorganized the documentation.

1.3 9 April 1999

Added function and call tags.

Added a tag for compressing whitespace.

Made variable delimiters in tags optional and deprecated.

Added convenience methods to SimpleHash and SimpleList, to take strings and booleans and add them as SimpleScalars.

Added another sample program.

Allowed variables in include statements.

Changed the license to LGPL.

1.2.2 7 April 1999

Fixed a bug that caused the expression parser to choke on complex expressions with unnecessary parentheses.

Made a few changes to allow the package to compile under JDK 1.1 with the 1.2 collections classes imported.

Some improvements to parser efficiency.

1.2.1 6 April 1999 Reorganized the source code into subpackages for clarity.
1.2 5 April 1999

Added switch-case tags.

Made the processing of compiled templates faster and more memory-efficient.

Fixed a bug that could cause the parser to get confused by JavaScript in rare cases.

1.1 30 March 1999 Added assign and include tags.

More efficient parser design.

Fixed a bug in the reporting of errors.

1.0 6 January 1999 First release version.