Files
struts/core
Lukasz Lenart 05ad78a069 WW-5690 perf(dispatcher): load the dev-mode error template on first use (#1864)
* WW-5690 perf(dispatcher): load the dev-mode error template on first use

DefaultDispatcherErrorHandler.init() built a FreeMarker configuration and
loaded /org/apache/struts2/dispatcher/error.ftl on every startup, including
in production where the problem report is never rendered - handleError()
delegates to the container's error page unless devMode is on.

Defer the load to the first dev-mode error instead. Two threads racing there
may both load the template, which is harmless: FreeMarker caches templates in
its own configuration, and that is cheaper than locking a path taken once per
application.

One behavioural change: a missing or unparsable error.ftl used to fail the
application at boot. It now surfaces on the first dev-mode error, where the
existing catch in handleErrorInDevMode() degrades to sendError() with the
cause. A dev-only template should not stop a production application starting.

This removes the startup cost only; the FreeMarker dependency itself stays.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* WW-5690 refactor(dispatcher): synchronise the lazy template load

Sonar flags the volatile Template field (java:S3077): volatile publishes the
reference safely but guarantees nothing about the object's own state, and
Template extends Configurable, so it is not strictly immutable.

The lock-free version was not worth defending anyway. It was justified as
avoiding a lock on a path taken once per application, but that path only runs
when devMode is on and a request has already failed - it is never hot. And
FreemarkerManager.getConfiguration is itself synchronized, so this path was
already taking a lock.

A plain field behind a synchronized getter is simpler, obviously correct, and
costs nothing here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 14:30:36 +02:00
..

Struts 2 Core

This is a core of the Apache Struts framework and all other modules depend on it. It requires Java 8 at minimum and a Servlet container supporting Java Servlet API 3.1 at least.

Installation

Just drop this plugin into WEB-INF/lib folder or add it as Maven dependency