Class Configuration

java.lang.Object
freemarker.core.Configurable
freemarker.template.Configuration
All Implemented Interfaces:
ParserConfiguration, Cloneable

public class Configuration extends Configurable implements Cloneable, ParserConfiguration
The main entry point into the FreeMarker API; encapsulates the configuration settings of FreeMarker, also serves as a central template-loading and caching service.

This class is meant to be used in a singleton pattern. That is, you create an instance of this at the beginning of the application life-cycle, set its configuration settings there (either with the setter methods like setTemplateLoader(TemplateLoader) or by loading a .properties file), and then use that single instance everywhere in your application. Frequently re-creating Configuration is a typical and grave mistake from performance standpoint, as the Configuration holds the template cache, and often also the class introspection cache, which then will be lost. (Note that, naturally, having multiple long-lived instances, like one per component that internally uses FreeMarker is fine.)

The basic usage pattern is like:

  // Where the application is initialized; in general you do this ONLY ONCE in the application life-cycle!
  Configuration cfg = new Configuration(VERSION_X_Y_Z));
  // Where VERSION_X_Y_Z enables the not-100%-backward-compatible fixes introduced in
  // FreeMarker version X.Y.Z  and earlier (see Configuration(Version)).
  cfg.setSomeSetting(...);
  cfg.setOtherSetting(...);
  ...
  
  // Later, whenever the application needs a template (so you may do this a lot, and from multiple threads):
  Template myTemplate = cfg.getTemplate("myTemplate.ftlh");
  myTemplate.process(dataModel, out);

A couple of settings that you should not leave on its default value are:

A Configuration object is thread-safe only after you have stopped modifying the configuration settings, and you have safely published it (see JSR 133 and related literature) to other threads. Generally, you set everything directly after you have instantiated the Configuration object, then you don't change the settings anymore, so then it's safe to make it accessible (again, via a "safe publication" technique) from multiple threads. The methods that aren't for modifying settings, like getTemplate(String), are thread-safe.

  • Field Details

    • DEFAULT_ENCODING_KEY_SNAKE_CASE

      public static final String DEFAULT_ENCODING_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • DEFAULT_ENCODING_KEY_CAMEL_CASE

      public static final String DEFAULT_ENCODING_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • DEFAULT_ENCODING_KEY

      public static final String DEFAULT_ENCODING_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • LOCALIZED_LOOKUP_KEY_SNAKE_CASE

      public static final String LOCALIZED_LOOKUP_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • LOCALIZED_LOOKUP_KEY_CAMEL_CASE

      public static final String LOCALIZED_LOOKUP_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • LOCALIZED_LOOKUP_KEY

      public static final String LOCALIZED_LOOKUP_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • STRICT_SYNTAX_KEY_SNAKE_CASE

      public static final String STRICT_SYNTAX_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • STRICT_SYNTAX_KEY_CAMEL_CASE

      public static final String STRICT_SYNTAX_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • STRICT_SYNTAX_KEY

      public static final String STRICT_SYNTAX_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • WHITESPACE_STRIPPING_KEY_SNAKE_CASE

      public static final String WHITESPACE_STRIPPING_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • WHITESPACE_STRIPPING_KEY_CAMEL_CASE

      public static final String WHITESPACE_STRIPPING_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • WHITESPACE_STRIPPING_KEY

      public static final String WHITESPACE_STRIPPING_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • OUTPUT_FORMAT_KEY_SNAKE_CASE

      public static final String OUTPUT_FORMAT_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • OUTPUT_FORMAT_KEY_CAMEL_CASE

      public static final String OUTPUT_FORMAT_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • OUTPUT_FORMAT_KEY

      public static final String OUTPUT_FORMAT_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_SNAKE_CASE

      public static final String RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE

      public static final String RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY

      public static final String RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE

      public static final String REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_CAMEL_CASE

      public static final String REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY

      public static final String REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • AUTO_ESCAPING_POLICY_KEY_SNAKE_CASE

      public static final String AUTO_ESCAPING_POLICY_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE

      public static final String AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • AUTO_ESCAPING_POLICY_KEY

      public static final String AUTO_ESCAPING_POLICY_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • CACHE_STORAGE_KEY_SNAKE_CASE

      public static final String CACHE_STORAGE_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • CACHE_STORAGE_KEY_CAMEL_CASE

      public static final String CACHE_STORAGE_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • CACHE_STORAGE_KEY

      public static final String CACHE_STORAGE_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • TEMPLATE_UPDATE_DELAY_KEY_SNAKE_CASE

      public static final String TEMPLATE_UPDATE_DELAY_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TEMPLATE_UPDATE_DELAY_KEY_CAMEL_CASE

      public static final String TEMPLATE_UPDATE_DELAY_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TEMPLATE_UPDATE_DELAY_KEY

      public static final String TEMPLATE_UPDATE_DELAY_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • AUTO_IMPORT_KEY_SNAKE_CASE

      public static final String AUTO_IMPORT_KEY_SNAKE_CASE
      Deprecated.
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • AUTO_IMPORT_KEY_CAMEL_CASE

      public static final String AUTO_IMPORT_KEY_CAMEL_CASE
      Deprecated.
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • AUTO_IMPORT_KEY

      public static final String AUTO_IMPORT_KEY
      Deprecated.
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • AUTO_INCLUDE_KEY_SNAKE_CASE

      public static final String AUTO_INCLUDE_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • AUTO_INCLUDE_KEY_CAMEL_CASE

      public static final String AUTO_INCLUDE_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • AUTO_INCLUDE_KEY

      public static final String AUTO_INCLUDE_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • TAG_SYNTAX_KEY_SNAKE_CASE

      public static final String TAG_SYNTAX_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TAG_SYNTAX_KEY_CAMEL_CASE

      public static final String TAG_SYNTAX_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TAG_SYNTAX_KEY

      public static final String TAG_SYNTAX_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • INTERPOLATION_SYNTAX_KEY_SNAKE_CASE

      public static final String INTERPOLATION_SYNTAX_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.28
      See Also:
      Constant Field Values
    • INTERPOLATION_SYNTAX_KEY_CAMEL_CASE

      public static final String INTERPOLATION_SYNTAX_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.28
      See Also:
      Constant Field Values
    • INTERPOLATION_SYNTAX_KEY

      public static final String INTERPOLATION_SYNTAX_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • NAMING_CONVENTION_KEY_SNAKE_CASE

      public static final String NAMING_CONVENTION_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • NAMING_CONVENTION_KEY_CAMEL_CASE

      public static final String NAMING_CONVENTION_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • NAMING_CONVENTION_KEY

      public static final String NAMING_CONVENTION_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • TAB_SIZE_KEY_SNAKE_CASE

      public static final String TAB_SIZE_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.25
      See Also:
      Constant Field Values
    • TAB_SIZE_KEY_CAMEL_CASE

      public static final String TAB_SIZE_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.25
      See Also:
      Constant Field Values
    • TAB_SIZE_KEY

      public static final String TAB_SIZE_KEY
      Alias to the ..._SNAKE_CASE variation. @since 2.3.25
      See Also:
      Constant Field Values
    • TEMPLATE_LOADER_KEY_SNAKE_CASE

      public static final String TEMPLATE_LOADER_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TEMPLATE_LOADER_KEY_CAMEL_CASE

      public static final String TEMPLATE_LOADER_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TEMPLATE_LOADER_KEY

      public static final String TEMPLATE_LOADER_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • TEMPLATE_LOOKUP_STRATEGY_KEY_SNAKE_CASE

      public static final String TEMPLATE_LOOKUP_STRATEGY_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TEMPLATE_LOOKUP_STRATEGY_KEY_CAMEL_CASE

      public static final String TEMPLATE_LOOKUP_STRATEGY_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TEMPLATE_LOOKUP_STRATEGY_KEY

      public static final String TEMPLATE_LOOKUP_STRATEGY_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • TEMPLATE_NAME_FORMAT_KEY_SNAKE_CASE

      public static final String TEMPLATE_NAME_FORMAT_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TEMPLATE_NAME_FORMAT_KEY_CAMEL_CASE

      public static final String TEMPLATE_NAME_FORMAT_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • TEMPLATE_NAME_FORMAT_KEY

      public static final String TEMPLATE_NAME_FORMAT_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • TEMPLATE_CONFIGURATIONS_KEY_SNAKE_CASE

      public static final String TEMPLATE_CONFIGURATIONS_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • TEMPLATE_CONFIGURATIONS_KEY_CAMEL_CASE

      public static final String TEMPLATE_CONFIGURATIONS_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
      See Also:
      Constant Field Values
    • TEMPLATE_CONFIGURATIONS_KEY

      public static final String TEMPLATE_CONFIGURATIONS_KEY
      Alias to the ..._SNAKE_CASE variation. @since 2.3.24
      See Also:
      Constant Field Values
    • INCOMPATIBLE_IMPROVEMENTS_KEY_SNAKE_CASE

      public static final String INCOMPATIBLE_IMPROVEMENTS_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • INCOMPATIBLE_IMPROVEMENTS_KEY_CAMEL_CASE

      public static final String INCOMPATIBLE_IMPROVEMENTS_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
      See Also:
      Constant Field Values
    • INCOMPATIBLE_IMPROVEMENTS_KEY

      public static final String INCOMPATIBLE_IMPROVEMENTS_KEY
      Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
      See Also:
      Constant Field Values
    • INCOMPATIBLE_IMPROVEMENTS

      @Deprecated public static final String INCOMPATIBLE_IMPROVEMENTS
      Deprecated.
      See Also:
      Constant Field Values
    • INCOMPATIBLE_ENHANCEMENTS

      @Deprecated public static final String INCOMPATIBLE_ENHANCEMENTS
      Deprecated.
      See Also:
      Constant Field Values
    • FALLBACK_ON_NULL_LOOP_VARIABLE_KEY_SNAKE_CASE

      public static final String FALLBACK_ON_NULL_LOOP_VARIABLE_KEY_SNAKE_CASE
      Legacy, snake case (like_this) variation of the setting name. @since 2.3.29
      See Also:
      Constant Field Values
    • FALLBACK_ON_NULL_LOOP_VARIABLE_KEY_CAMEL_CASE

      public static final String FALLBACK_ON_NULL_LOOP_VARIABLE_KEY_CAMEL_CASE
      Modern, camel case (likeThis) variation of the setting name. @since 2.3.29
      See Also:
      Constant Field Values
    • FALLBACK_ON_NULL_LOOP_VARIABLE_KEY

      public static final String FALLBACK_ON_NULL_LOOP_VARIABLE_KEY
      Alias to the ..._SNAKE_CASE variation. @since 2.3.25
      See Also:
      Constant Field Values
    • AUTO_DETECT_TAG_SYNTAX

      public static final int AUTO_DETECT_TAG_SYNTAX
      The parser decides between ANGLE_BRACKET_TAG_SYNTAX and SQUARE_BRACKET_TAG_SYNTAX based on the first tag (like [#if x] or <#if x>) it mets. Note that [=...] is not a tag, but an interpolation, so it's not used for tag syntax auto-detection.
      See Also:
      Constant Field Values
    • ANGLE_BRACKET_TAG_SYNTAX

      public static final int ANGLE_BRACKET_TAG_SYNTAX
      For example <#if x><@foo /></#if>
      See Also:
      Constant Field Values
    • SQUARE_BRACKET_TAG_SYNTAX

      public static final int SQUARE_BRACKET_TAG_SYNTAX
      For example [#if x][@foo /][/#if]. It does not change ${x} to [=x]; that's square bracket interpolation syntax (SQUARE_BRACKET_INTERPOLATION_SYNTAX).
      See Also:
      Constant Field Values
    • LEGACY_INTERPOLATION_SYNTAX

      public static final int LEGACY_INTERPOLATION_SYNTAX
      ${expression} and the deprecated #{expression; numFormat} @since 2.3.28
      See Also:
      Constant Field Values
    • DOLLAR_INTERPOLATION_SYNTAX

      public static final int DOLLAR_INTERPOLATION_SYNTAX
      ${expression} only (not #{expression; numFormat}) @since 2.3.28
      See Also:
      Constant Field Values
    • SQUARE_BRACKET_INTERPOLATION_SYNTAX

      public static final int SQUARE_BRACKET_INTERPOLATION_SYNTAX
      [=expression] instead of ${expression}. It does not change <#if x> to [#if x]; that's square bracket tag syntax (SQUARE_BRACKET_TAG_SYNTAX).
      Since:
      2.3.28
      See Also:
      Constant Field Values
    • AUTO_DETECT_NAMING_CONVENTION

      public static final int AUTO_DETECT_NAMING_CONVENTION
      See Also:
      Constant Field Values
    • LEGACY_NAMING_CONVENTION

      public static final int LEGACY_NAMING_CONVENTION
      See Also:
      Constant Field Values
    • CAMEL_CASE_NAMING_CONVENTION

      public static final int CAMEL_CASE_NAMING_CONVENTION
      See Also:
      Constant Field Values
    • DISABLE_AUTO_ESCAPING_POLICY

      public static final int DISABLE_AUTO_ESCAPING_POLICY
      Don't enable auto-escaping, regardless of what the OutputFormat is. Note that a <#ftl auto_esc=true> in the template will override this.
      See Also:
      Constant Field Values
    • ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY

      public static final int ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY
      Enable auto-escaping if the output format supports it and MarkupOutputFormat.isAutoEscapedByDefault() is true.
      See Also:
      Constant Field Values
    • ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY

      public static final int ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY
      Enable auto-escaping if the OutputFormat supports it.
      See Also:
      Constant Field Values
    • FORCE_AUTO_ESCAPING_POLICY

      public static final int FORCE_AUTO_ESCAPING_POLICY
      This policy is to always require auto-escaping, to avoid accidents where because of misconfiguration, or a mistake of the template author it's disabled. With this policy, using output formats that don't support escaping will not be allowed. Using built-ins, and directives that disable auto-escaping (like ?no_esc) will also be errors (on parse-time). Note that if markup (like HTML) comers from the data model, then with this policy you will have to ensure that they come as TemplateMarkupOutputModel-s (which won't be auto-escaped even with this policy), not as String-s, because the template authors can't disable escaping for the value anymore.
      See Also:
      Constant Field Values
    • VERSION_2_3_0

      public static final Version VERSION_2_3_0
      FreeMarker version 2.3.0 (an incompatible improvements break-point)
    • VERSION_2_3_19

      public static final Version VERSION_2_3_19
      FreeMarker version 2.3.19 (an incompatible improvements break-point)
    • VERSION_2_3_20

      public static final Version VERSION_2_3_20
      FreeMarker version 2.3.20 (an incompatible improvements break-point)
    • VERSION_2_3_21

      public static final Version VERSION_2_3_21
      FreeMarker version 2.3.21 (an incompatible improvements break-point)
    • VERSION_2_3_22

      public static final Version VERSION_2_3_22
      FreeMarker version 2.3.22 (an incompatible improvements break-point)
    • VERSION_2_3_23

      public static final Version VERSION_2_3_23
      FreeMarker version 2.3.23 (an incompatible improvements break-point)
    • VERSION_2_3_24

      public static final Version VERSION_2_3_24
      FreeMarker version 2.3.24 (an incompatible improvements break-point)
    • VERSION_2_3_25

      public static final Version VERSION_2_3_25
      FreeMarker version 2.3.25 (an incompatible improvements break-point)
    • VERSION_2_3_26

      public static final Version VERSION_2_3_26
      FreeMarker version 2.3.26 (an incompatible improvements break-point)
    • VERSION_2_3_27

      public static final Version VERSION_2_3_27
      FreeMarker version 2.3.27 (an incompatible improvements break-point)
    • VERSION_2_3_28

      public static final Version VERSION_2_3_28
      FreeMarker version 2.3.28 (an incompatible improvements break-point)
    • VERSION_2_3_29

      public static final Version VERSION_2_3_29
      FreeMarker version 2.3.29 (an incompatible improvements break-point)
    • VERSION_2_3_30

      public static final Version VERSION_2_3_30
      FreeMarker version 2.3.30 (an incompatible improvements break-point)
    • VERSION_2_3_31

      public static final Version VERSION_2_3_31
      FreeMarker version 2.3.31 (an incompatible improvements break-point)
    • VERSION_2_3_32

      public static final Version VERSION_2_3_32
      FreeMarker version 2.3.32 (an incompatible improvements break-point)
    • VERSION_2_3_33

      public static final Version VERSION_2_3_33
      FreeMarker version 2.3.33 (an incompatible improvements break-point)
    • DEFAULT_INCOMPATIBLE_IMPROVEMENTS

      public static final Version DEFAULT_INCOMPATIBLE_IMPROVEMENTS
      The default of getIncompatibleImprovements(), currently VERSION_2_3_0.
    • DEFAULT_INCOMPATIBLE_ENHANCEMENTS

      @Deprecated public static final String DEFAULT_INCOMPATIBLE_ENHANCEMENTS
      Deprecated.
    • PARSED_DEFAULT_INCOMPATIBLE_ENHANCEMENTS

      @Deprecated public static final int PARSED_DEFAULT_INCOMPATIBLE_ENHANCEMENTS
      Deprecated.
  • Constructor Details

    • Configuration

      @Deprecated public Configuration()
      Deprecated.
      Use Configuration(Version) instead. Note that the version can be still modified later with setIncompatibleImprovements(Version) (or Configurable.setSettings(Properties)).
    • Configuration

      public Configuration(Version incompatibleImprovements)
      Creates a new instance and sets which of the non-backward-compatible bugfixes/improvements should be enabled. Note that the specified versions corresponds to the incompatible_improvements configuration setting, and can be changed later, with setIncompatibleImprovements(Version) for example.

      About the "incompatible improvements" setting

      This setting value is the FreeMarker version number where the not 100% backward compatible bug fixes and improvements that you want to enable were already implemented. In new projects you should set this to the fixed FreeMarker version that you start the development with. In older projects it's also usually better to keep this high, however you should check the changes activated (find them below), especially if not only the 3rd version number (the micro version) of incompatibleImprovements is increased. Generally, as far as you only increase the last version number of this setting, the changes are low risk. The default value is 2.3.0 to maximize backward compatibility, but that value isn't recommended.

      Bugfixes and improvements that are fully backward compatible, also those that are important security fixes, are enabled regardless of the incompatible improvements setting.

      Do NOT ever use getVersion() to set the "incompatible improvements". Always use a fixed value, like VERSION_2_3_33. Otherwise, your application can break as you upgrade FreeMarker. (As of 2.3.30, doing this will be logged as an error. As of 2.4.0, it will be probably disallowed, by throwing exception.)

      An important consequence of setting this setting is that now your application will check if the stated minimum FreeMarker version requirement is met. Like if you set this setting to 2.3.22, but accidentally the application is deployed with FreeMarker 2.3.21, then FreeMarker will fail, telling that a higher version is required. After all, the fixes/improvements you have requested aren't available on a lower version.

      Note that as FreeMarker's minor (2nd) or major (1st) version number increments, it's possible that emulating some of the old bugs will become unsupported, that is, even if you set this setting to a low value, it silently won't bring back the old behavior anymore. Information about that will be present here.

      Note that DefaultObjectWrapper (and BeansWrapper, which it extends) has its own "incompatible improvements" setting (see DefaultObjectWrapper(Version)), but if you leave the object_wrapper setting at its default (and most do), then that will be kept the same as of the Configuration.

      Currently the effects of this setting are:

      • 2.3.0: This is the lowest supported value, the version used in very old projects. This is the default in the FreeMarker 2.3.x series (the one used by the deprecated Configuration() constructor) for maximum backward compatibility.

      • 2.3.19 (or higher): Bug fix: Wrong # tags were printed as static text instead of causing parsing error when there was no correct # or @ tag earlier in the same template.

      • 2.3.20 (or higher): ?html will escape apostrophe-quotes just like ?xhtml does. Utilizing this is highly recommended, because otherwise if interpolations are used inside attribute values that use apostrophe-quotation (<foo bar='${val}'>) instead of plain quotation mark (<foo bar="${val}">), they might produce HTML/XML that's not well-formed. Note that ?html didn't do this because long ago there was no cross-browser way of doing this, but it's not a concern anymore.

      • 2.3.21 (or higher):

        • The default of the object_wrapper setting (Configurable.getObjectWrapper()) changes from ObjectWrapper.DEFAULT_WRAPPER to another almost identical DefaultObjectWrapper singleton, returned by DefaultObjectWrapperBuilder.build(). The new default object wrapper's "incompatible improvements" version is set to the same as of the Configuration. See BeansWrapper(Version) for further details. Furthermore, the new default object wrapper doesn't allow changing its settings; setter methods throw IllegalStateException). (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 to other threads.) Furthermore the new default object wrapper shares class introspection cache with other BeansWrapper-s created with BeansWrapperBuilder, which has an impact as BeansWrapper.clearClassIntrospectionCache() will be disallowed; see more about it there.

        • The ?iso_... built-ins won't show the time zone offset for Time values anymore, because most databases store time values that aren't in any time zone, but just store hour, minute, second, and decimal second field values. If you still want to show the offset (like for PostgreSQL "time with time zone" columns you should), you can force showing the time zone offset by using myTime?string.iso_fz (and its other variants).

        • ?is_enumerable correctly returns false for Java methods get from Java objects that are wrapped with BeansWrapper and its subclasses, like DefaultObjectWrapper. Although method values implement TemplateSequenceModel (because of a historical design quirk in BeansWrapper), trying to #list them will cause error, hence they aren't enumerable.

        • ?c will return "INF", "-INF" and "NaN" 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 DecimalFormat did with US locale, none of which was understood by any (common) computer language.

        • FTL hash literals that repeat keys now only have the key once with ?keys, and only has the last value associated to that key with ?values. This is consistent with the behavior of hash[key] and how maps work in Java.

        • In most cases (where FreeMarker is able to do that), for TemplateLoader-s that use URLConnection, URLConnection#setUseCaches(boolean) will called with false, so that only FreeMarker will do caching, not the URL scheme's handler. See URLTemplateLoader.setURLConnectionUsesCaches(Boolean) for more details.

        • The default of the template_loader setting (getTemplateLoader()) changes to null, which means that FreeMarker will not find any templates. Earlier the default was a FileTemplateLoader 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 the template_loader setting, so it's unlikely that changing the default breaks your application.

        • Right-unlimited ranges become readable (like listable), so <#list 1.. as i>...</#list> works. Earlier they were only usable for slicing (like hits[10..]).

        • Empty ranges return Constants.EMPTY_SEQUENCE instead of an empty SimpleSequence. This is in theory backward compatible, as the API only promises to give something that implements TemplateSequenceModel.

        • Unclosed comments (<#-- ...) and #noparse-s won't be silently closed at the end of template anymore, but cause a parsing error instead.

      • 2.3.22 (or higher):

        • DefaultObjectWrapper has some substantial changes with incompatibleImprovements 2.3.22; check them out at DefaultObjectWrapper(Version). It's important to know that if you set the object_wrapper setting (to an other value than "default"), rather than leaving it on its default value, the object_wrapper won't inherit the incompatibleImprovements of the Configuration. In that case, if you want the 2.3.22 improvements of DefaultObjectWrapper, you have to set it in the DefaultObjectWrapper object itself too! (Note that it's OK to use a DefaultObjectWrapper with a different incompatibleImprovements version number than that of the Configuration, if that's really what you want.)

        • In templates, .template_name will always return the main (top level) template's name. It won't be affected by #include and #nested anymore. This is unintended, a bug with incompatible_improvement 2.3.22 (a consequence of the lower level fixing described in the next point). The old behavior of .template_name is restored if you set incompatible_improvement to 2.3.23 (while Configurable.getParent() of Environment keeps the changed behavior shown in the next point).

        • #include and #nested doesn't change the parent Template (see Configurable.getParent()) of the Environment anymore to the Template that's included or whose namespace #nested "returns" to. Thus, the parent of Environment will be now always the main Template. (The main Template is the Template whose process or createProcessingEnvironment method was called to initiate the output generation.) Note that apart from the effect on FTL's .template_name (see previous point), this should only matter if you have set settings directly on Template objects, and almost nobody does that. Also note that macro calls have never changed the Environment parent to the Template that contains the macro definition, so this mechanism was always broken. As now we consistently never change the parent, the behavior when calling macros didn't change.

        • When using freemarker.ext.servlet.FreemarkerServlet:

          • When using custom JSP tag libraries: Fixes bug where some kind of values, when put into the JSP page scope (via #global or via the JSP PageContext API) and later read back with the JSP PageContext API (typically in a custom JSP tag), might come back as FreeMarker TemplateModel objects instead of as objects with a standard Java type. Other Servlet scopes aren't affected. It's highly unlikely that something expects the presence of this bug. The affected values are of the FTL types listed below, and to trigger the bug, they either had to be created directly in the template (like as an FTL literal or with ?date/time/datetime), or you had to use DefaultObjectWrapper or SimpleObjectWrapper (or a subclass of them):

          • Initial "[" in the TemplatePath init-param has special meaning; it's used for specifying multiple comma separated locations, like in <param-value>[ WEB-INF/templates, classpath:com/example/myapp/templates ]</param-value>

          • Initial "{" in the TemplatePath init-param is reserved for future purposes, and thus will throw exception.

      • 2.3.23 (or higher):

        • Fixed a loophole in the implementation of the long existing parse-time rule that says that #break, in the FTL source code itself, must occur nested inside a breakable directive, such as #list or #switch. This check could be circumvented with #macro or #function, like this: <#list 1..1 as x><#macro callMeLater><#break></#macro></#list><@callMeLater />. After activating this fix, this will be a parse time error.

        • If you have used incompatible_improvements 2.3.22 earlier, know that there the behavior of the .template_name special variable used in templates was accidentally altered, but now it's restored to be backward compatible with 2.3.0. (Ironically, the restored legacy behavior itself is broken when it comes to macro invocations, we just keep it for backward compatibility. If you need fixed behavior, use .current_template_name or .main_template_name instead.)

      • 2.3.24 (or higher):

        • The default of the recognize_standard_file_extensions setting changes to true, which means that templates whose name ends with ".ftlh" or ".ftlx" will automatically get HTMLOutputFormat.INSTANCE or XMLOutputFormat.INSTANCE output format respectively, in both cases with ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY auto_escaping_policy. These "file" extensions aren't case sensitive.

        • In number format and date format strings (like in the number_format setting, or in templates in n?string("0.##")), an initial '@' has special meaning; they refer to a custom format with the name given after the @ (see: Configurable.setCustomNumberFormats(Map), Configurable.setCustomDateFormats(Map), Configurable.setNumberFormat(String), and Configurable.setDateTimeFormat(java.lang.String)). If the custom format doesn't exist, that will be an error. To have a literal @ as the first character in the output, it has to be written as @@. Again, all this only applies to the very first character of the format string, so @ characters elsewhere must not be doubled. Also, if there are any custom formats defined, initial '@' will have the new meaning regardless of the value of the incompatible_improvements setting. So you don't need to set the incompatible_improvements only to use custom formats.

        • Expressions inside interpolations that were inside string literal expressions (not ${...}-s in general), like in <#assign s="Hello ${name}!">, has always used incompatbileImprovement-s 0 (2.3.0 in effect). Now it's fixed.

        • DefaultObjectWrapper has some minor changes with incompatibleImprovements 2.3.24; check them out at DefaultObjectWrapper(Version). It's important to know that if you set the object_wrapper setting (to an other value than "default"), rather than leaving it on its default value, the object_wrapper won't inherit the incompatibleImprovements of the Configuration. In that case, if you want the 2.3.24 improvements of DefaultObjectWrapper, you have to set it in the DefaultObjectWrapper object itself too! (Note that it's OK to use a DefaultObjectWrapper with a different incompatibleImprovements version number than that of the Configuration, if that's really what you want.)

        • Fixed bug: The #import directive meant to copy the library variable into a global variable if it's executed in the main namespace, but that haven't happened when the imported template was already imported earlier in another namespace.

        • ?is_sequence doesn't return true for Java methods wrapped by BeansWrapper and its subclasses (most notably DefaultObjectWrapper) anymore, as they only implement the [index] operator, but not ?size, which causes <#list ...> to fail among others. (They shouldn't implement either, but this is historical heritage.)

      • 2.3.25 (or higher):

      • 2.3.26 (or higher):

      • 2.3.27 (or higher):

      • 2.3.28 (or higher):

        • When calling a macro or function (things defined in a template, not directly in Java) and the argument list contains .current_template_name, now it will correctly evaluate to the template that contains the call, rather than to the template that contains the macro or function definition. (Of course, the parameter default value expression is still evaluated in the context of the called macro or function.) Similarly, .macro_caller_template_name (which itself was added in 2.3.28), when used in a macro call argument, won't be incorrectly evaluated in the context of the called macro.

        • Fixed legacy parser glitch where a tag can be closed with an illegal ] (when it's not part of an expression) despite that the tag syntax is set to angle brackets. For example <#if x] worked just like <#if x>. Note that it doesn't affect the legal usage of ], like <#if x[0]> works correctly without this fix as well.

      • 2.3.31 (or higher):

        • When you set the number_format setting to "computer" (or you call Environment.getCNumberFormat()), the format now matches the behavior of ?c, when formatting infinite (positive and negative), and NaN. Matching the behavior of ?c was always the intent, but before this incompatible improvement, the "computer" format always behaved like ?c before Incompatible Improvements 2.3.21, where instead of INF, and NaN, the results used unicode characters U+221E, and U+FFFD.

      • 2.3.32 (or higher):

        • The number formatting of ?c, ?cn (and thus also of the "c", and "computer" number_format) changes, if the c_format setting was left on its default. The default of c_format changes to JavaScriptOrJSONCFormat.INSTANCE, from LegacyCFormat.INSTANCE, and that's what contains the changes:

          • Changes affecting non-whole numbers, and whole numbers with over 100 digits: Formatting is now lossless, so it potentially shows much more decimals. It now uses exponential format (like 1.2E-7 instead of 0.00000012) for numbers whose absolute value is less than 1E-6 (0.000001), and for whole numbers whose absolute value is at least 1E101 (so over 100 digits). It also uses exponential format for whole floating point (double/Double}, or float/Float) numbers, when their absolute value is too big for the floating point type to store them precisely (so if the intent was to store some ID-s, they are likely corrupted anyway, as the type skips some whole numbers).

          • Changes affecting floating point infinity: Output changes from INF to Infinity, which is the JavaScript and JSON syntax. If you generate XML with XSD-style number syntax (which uses INF), but you want the other number formatting changes (recommended), then set c_format to XSCFormat.INSTANCE/"XS".

      • 2.3.33 (or higher):

        • Comparing strings is now way faster. If your template does lot of string comparisons, this can mean very significant speedup. We now use a simpler way of comparing strings, and because templates were only ever allowed equality comparisons between strings (not less-than, or greater-than), it's very unlikely to change the behavior of your templates. (Technically, what changes is that instead of using Java's localized Collator-s, we switch to a simple binary comparison after UNICODE NFKC normalization. So, in theory it's possible that for some locales two different but similarly looking characters were treated as equal by the collator, but will count as different now. But it's very unlikely that anyone wanted to depend on such fragile logic anyway. Note again that we still do UNICODE normalization, so combining characters won't break your comparisons.)

        • The default object_wrapper now exposes Java records public methods with 0-arguments and non-void return type are now exposed both as properties, and as methods; see BeansWrapper(Version).

      Throws:
      IllegalArgumentException - If incompatibleImmprovements refers to a version that wasn't released yet when the currently used FreeMarker version was released, or is less than 2.3.0, or is null.
      Since:
      2.3.21
  • Method Details