Summary
The appended-.vm path uses the global static Velocity singleton, while the rest of the plugin uses a per-mojo VelocityEngine instance. Both mojos are marked threadSafe = true.
src/main/java/org/apache/maven/plugin/resources/remote/AbstractProcessRemoteResourcesMojo.java:976-985
} else if (appendedVmResourceFile.exists()) {
...
try (CachingOutputStream os = new CachingOutputStream(outputFile);
Reader reader = getReader(bundle.getSourceEncoding(), appendedVmResourceFile);
Writer writer = getWriter(bundle.getSourceEncoding(), os)) {
Velocity.init();
Velocity.evaluate(context, writer, "remote-resources", reader);
}
}
Meanwhile the template path uses the instance engine configured in execute() (:442-445) with a classpath resource loader. The static Velocity runtime is JVM-global: Velocity.init()/Velocity.evaluate() mutate and run against shared state.
Impact
In parallel Maven builds (-T), two modules can invoke Velocity.init()/Velocity.evaluate() concurrently on the same global runtime; the static singleton is also shared with any other component using Velocity in the same JVM. The instance engine and global singleton are configured independently (different resource loaders/TCCL assumptions), so behavior can differ and race between the two code paths.
Suggested fix
Use the instance velocity engine for the appended-.vm evaluation as well (drop the Velocity.init()/Velocity.evaluate static calls), or document why the global singleton is required. Also reconsider threadSafe = true on ProcessRemoteResourcesMojo/AggregateProcessRemoteResourcesMojo given the global state.
Summary
The appended-
.vmpath uses the global staticVelocitysingleton, while the rest of the plugin uses a per-mojoVelocityEngineinstance. Both mojos are markedthreadSafe = true.src/main/java/org/apache/maven/plugin/resources/remote/AbstractProcessRemoteResourcesMojo.java:976-985Meanwhile the template path uses the instance engine configured in
execute()(:442-445) with a classpath resource loader. The staticVelocityruntime is JVM-global:Velocity.init()/Velocity.evaluate()mutate and run against shared state.Impact
In parallel Maven builds (
-T), two modules can invokeVelocity.init()/Velocity.evaluate()concurrently on the same global runtime; the static singleton is also shared with any other component usingVelocityin the same JVM. The instance engine and global singleton are configured independently (different resource loaders/TCCL assumptions), so behavior can differ and race between the two code paths.Suggested fix
Use the instance
velocityengine for the appended-.vmevaluation as well (drop theVelocity.init()/Velocity.evaluatestatic calls), or document why the global singleton is required. Also reconsiderthreadSafe = trueonProcessRemoteResourcesMojo/AggregateProcessRemoteResourcesMojogiven the global state.