From cc6d5a68af03685fa2e1f66270ea6566b500dd14 Mon Sep 17 00:00:00 2001 From: Sylwester Lachiewicz Date: Sat, 8 Aug 2026 18:52:46 +0200 Subject: [PATCH] Keep verbatim source blocks working with Doxia 1 SinkEventAttributeSet.SOURCE was added in Doxia 2, replacing BOXED, so reading it ends in NoSuchFieldError whenever the Maven Site Plugin in use still provides Doxia 1. That is the same failure that MPIR issue 103 reported for verbatimText and verbatimLink, one method over, and it is reachable: maven-plugin-report-plugin calls verbatimSource. Build the attribute set instead. The decoration key and the varargs constructor both exist in Doxia 1 and 2, so the block renders as source on Doxia 2 as before, and degrades to a plain verbatim block on Doxia 1 rather than failing the report. --- .../AbstractMavenReportRenderer.java | 6 ++- .../AbstractMavenReportRendererTest.java | 44 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java b/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java index 71a479f..2e9f593 100644 --- a/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java +++ b/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java @@ -386,7 +386,11 @@ protected void verbatimLink(String text, String href) { * @see Sink#verbatim_() */ protected void verbatimSource(String source) { - sink.verbatim(SinkEventAttributeSet.SOURCE); + // not SinkEventAttributeSet.SOURCE: that constant only exists since Doxia 2, where it replaced BOXED, + // and report plugins run against the Doxia the Maven Site Plugin provides, which may still be Doxia 1. + // Building the same attribute set by hand keeps this a plain verbatim block there instead of a + // NoSuchFieldError (MPIR issue 103 was the same problem one method over). + sink.verbatim(new SinkEventAttributeSet(SinkEventAttributes.DECORATION, "source")); text(source); diff --git a/src/test/java/org/apache/maven/reporting/AbstractMavenReportRendererTest.java b/src/test/java/org/apache/maven/reporting/AbstractMavenReportRendererTest.java index 36972f4..e416735 100644 --- a/src/test/java/org/apache/maven/reporting/AbstractMavenReportRendererTest.java +++ b/src/test/java/org/apache/maven/reporting/AbstractMavenReportRendererTest.java @@ -21,14 +21,18 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.doxia.sink.SinkEventAttributes; +import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.fail; /** @@ -167,4 +171,44 @@ protected void renderBody() { assertEquals(2, verbatimCalls.get()); } + + /** + * Same reasoning for {@code verbatimSource}, one level down: the attribute set has to be built rather than + * read off {@code SinkEventAttributeSet.SOURCE}, which is only there since Doxia 2. Asserting the identity + * rather than only the content is what makes this fail if the constant is used again, since the constant + * carries exactly the same attribute. + */ + @Test + void verbatimSourceBuildsTheAttributeSetRatherThanReadingTheDoxia2Constant() { + List verbatimAttributes = new ArrayList<>(); + Sink sink = (Sink) Proxy.newProxyInstance( + getClass().getClassLoader(), new Class[] {Sink.class}, (proxy, method, args) -> { + if ("verbatim".equals(method.getName()) && method.getParameterCount() == 1) { + verbatimAttributes.add((SinkEventAttributes) args[0]); + } + return null; + }); + + AbstractMavenReportRenderer renderer = new AbstractMavenReportRenderer(sink) { + @Override + public String getTitle() { + return "title"; + } + + @Override + protected void renderBody() { + verbatimSource("var code = true;"); + } + }; + + renderer.render(); + + assertEquals(1, verbatimAttributes.size()); + SinkEventAttributes attributes = verbatimAttributes.get(0); + assertEquals("source", attributes.getAttribute(SinkEventAttributes.DECORATION)); + assertNotSame( + SinkEventAttributeSet.SOURCE, + attributes, + "SinkEventAttributeSet.SOURCE does not exist in Doxia 1 and must not be read"); + } }