[
https://issues.apache.org/jira/browse/WW-5690?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Lukasz Lenart updated WW-5690:
------------------------------
Description:
{{DefaultDispatcherErrorHandler.init()}} built a FreeMarker configuration and
loaded {{/org/apache/struts2/dispatcher/error.ftl}} on *every* startup —
including production, where the problem report is never rendered.
{{handleError(...)}} only reaches it when devMode is on; otherwise it delegates
to the container's error page via {{sendErrorResponse(...)}}.
So every Struts application paid to initialise FreeMarker for a page most of
them never show.
h2. Change
{{init(ServletContext)}} now only stores the servlet context. A new {{protected
getTemplate()}} loads the template on first use and caches it in a {{volatile}}
field.
No lock: two threads racing on the very first error may both load it, which is
harmless — FreeMarker caches templates in its own {{Configuration}} — and
cheaper than locking a path taken once per application lifetime.
h2. Behavioural change
A missing or unparsable {{error.ftl}} used to throw {{StrutsException}} from
{{init()}} and fail the application at boot. It now surfaces on the first
dev-mode error, where the existing {{catch}} in {{handleErrorInDevMode(...)}}
degrades to {{sendError(code, "Unable to show problem report: ...")}}. A
dev-only template should not stop a production application starting.
h2. Scope
Startup cost only. The {{FreemarkerManager}} injection, the
{{freemarker.template.Template}} import and {{error.ftl}} itself all remain —
removing them is WW-5693.
This ticket was originally filed as "Remove core's FreeMarker dependency from
DefaultDispatcherErrorHandler" and has been narrowed to the change that
actually shipped.
was:
Part of the WW-5689 lean-core work, but self-contained and shippable in 7.x.
*Scope note.* This is about _core's own_ dependency on FreeMarker. Applications
using the Struts tag library still require FreeMarker regardless:
{{struts.ui.templateSuffix}} defaults to {{ftl}} and all 129 bundled theme
templates are {{.ftl}}. What these tickets buy is that a REST/JSON-only
application — one that never renders a tag — stops paying for FreeMarker.
h2. Current behaviour
{{DefaultDispatcherErrorHandler}} renders the dev-mode error report through
FreeMarker:
* it holds an injected {{FreemarkerManager}}
* {{init(ServletContext)}} calls {{freemarkerManager.getConfiguration(ctx)}}
and loads {{/org/apache/struts2/dispatcher/error.ftl}}
* only {{handleErrorInDevMode(...)}} ever uses the resulting template
{{init()}} is *unconditional*. It runs at dispatcher startup and initialises
the whole FreeMarker configuration even in production mode, where the template
is never rendered — {{handleError(...)}} goes to {{sendErrorResponse(...)}} and
delegates to the container's error page.
h2. Proposal
Render the dev-mode error report without FreeMarker — a plain Java renderer is
sufficient for what {{error.ftl}} produces.
Failing that, the minimum acceptable change is to make the template load lazy
and gate it on devMode, so a production deployment never touches FreeMarker
through this path.
{{DispatcherErrorHandler}} is already a pluggable bean, so a FreeMarker-based
handler can remain available for anyone who has customised {{error.ftl}}.
h2. Compatibility
{{error.ftl}} is an internal template, not a documented extension point. If the
plain renderer lands, note the change in the migration guide for anyone who has
overridden it.
Summary: Defer loading the dev-mode error template until first use
(was: Remove core's FreeMarker dependency from DefaultDispatcherErrorHandler)
> Defer loading the dev-mode error template until first use
> ---------------------------------------------------------
>
> Key: WW-5690
> URL: https://issues.apache.org/jira/browse/WW-5690
> Project: Struts 2
> Issue Type: Task
> Components: Core
> Reporter: Lukasz Lenart
> Assignee: Lukasz Lenart
> Priority: Major
> Fix For: 7.4.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> {{DefaultDispatcherErrorHandler.init()}} built a FreeMarker configuration and
> loaded {{/org/apache/struts2/dispatcher/error.ftl}} on *every* startup —
> including production, where the problem report is never rendered.
> {{handleError(...)}} only reaches it when devMode is on; otherwise it
> delegates to the container's error page via {{sendErrorResponse(...)}}.
> So every Struts application paid to initialise FreeMarker for a page most of
> them never show.
> h2. Change
> {{init(ServletContext)}} now only stores the servlet context. A new
> {{protected getTemplate()}} loads the template on first use and caches it in
> a {{volatile}} field.
> No lock: two threads racing on the very first error may both load it, which
> is harmless — FreeMarker caches templates in its own {{Configuration}} — and
> cheaper than locking a path taken once per application lifetime.
> h2. Behavioural change
> A missing or unparsable {{error.ftl}} used to throw {{StrutsException}} from
> {{init()}} and fail the application at boot. It now surfaces on the first
> dev-mode error, where the existing {{catch}} in {{handleErrorInDevMode(...)}}
> degrades to {{sendError(code, "Unable to show problem report: ...")}}. A
> dev-only template should not stop a production application starting.
> h2. Scope
> Startup cost only. The {{FreemarkerManager}} injection, the
> {{freemarker.template.Template}} import and {{error.ftl}} itself all remain —
> removing them is WW-5693.
> This ticket was originally filed as "Remove core's FreeMarker dependency from
> DefaultDispatcherErrorHandler" and has been narrowed to the change that
> actually shipped.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)