Skip to content

Velocity: fail loud when global macro library load fails (follow-up to spike #35329) #35601

@dsolistorres

Description

@dsolistorres

Description

Spike #35329 confirmed the root cause of the recurring "macros render as literal text after pod restart" issue: dotCMS's patched VelocimacroFactory silently swallows ResourceNotFoundException when loading the configured velocimacro.library files (VM_global_library.vm, dotCMS_library.vm, dotCMS_library_ext.vm) at engine init time.

See dotCMS/src/main/java/org/apache/velocity/runtime/VelocimacroFactory.java:194-217:

try {
    Template template = rsvc.getTemplate(lib);
    ...
} catch(ResourceNotFoundException rnse){
    Logger.warn(this.getClass(), rnse.getMessage());   // ← silent
} catch (Exception e) {
    throw new VelocityException(msg, e);                // ← Apache's original behavior
}

When the resource lookup fails (a transient I/O error during early startup, e.g. EFS-backed volumes in K8s), engine.init() returns successfully and the engine reports ready, but the global macro library is never registered. #renderMarks($element) and #editContentlet then render as literal text on every public page until the JVM is restarted.

Acceptance Criteria

  • New config flag velocimacro.library.fail-on-missing (default false) added to dotCMS/src/main/resources/system.properties.
  • When the flag is true and any configured velocimacro.library file throws ResourceNotFoundException during init, engine.init() throws VelocityException with the failed library file name in the message (matches Apache's original fail-fast behavior).
  • When the flag is false, the current silent-warn behavior is preserved (backward-compat for self-hosted operators that may rely on optional libraries).
  • The Logger.warn at VelocimacroFactory.java:209 is upgraded to Logger.error regardless of the flag value, with the library file name in the message.
  • After the macro-library for-loop completes, an INFO log line summarizes load results — greppable in startup logs (e.g. Velocimacro libraries loaded: VM_global_library.vm=OK, dotCMS_library.vm=OK, ...).
  • Unit test (in dotCMS/src/test/java/com/dotcms/rendering/velocity/util/VelocityUtilTest.java or new test class): simulating ResourceNotFoundException for VM_global_library.vm throws VelocityException when flag is true.
  • Unit test: same simulation with flag=false logs an error and returns normally.
  • No regression in dotcms-integration/src/test/java/com/dotcms/rendering/velocity/VelocityUtilTest.java.

Additional Context

  • Companion ticket: VelocityHealthCheck readiness probe — that ticket prevents K8s from routing traffic to a pod in this broken state. This ticket prevents the broken state from being silent in the first place.
  • Files changed (expected): VelocimacroFactory.java, system.properties, plus tests.

Additional Note

  • We should discuss if the default value for the new config flag velocimacro.library.fail-on-missing should be true or false. If we set to false, we still have the warning in the log and also the new VelocityHealthCheck will alert about the problem. We can confirm with the cloud team if this behavior will work fine for cloud environments or if a better solution can be implemented.

Metadata

Metadata

Assignees

Type

No fields configured for Task.

Projects

Status

In Review

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions