This is an automated email from the ASF dual-hosted git repository.

vy pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


The following commit(s) were added to refs/heads/2.x by this push:
     new bf873ae58e Extend plugin processor message filtering and add `[Log4j]` 
prefixes (#4228)
bf873ae58e is described below

commit bf873ae58e75cb2296ad29c8df9691793e3f3dcf
Author: DragonFSKY <[email protected]>
AuthorDate: Fri Aug 14 17:07:29 2026 +0800

    Extend plugin processor message filtering and add `[Log4j]` prefixes (#4228)
    
    Co-authored-by: Ramanathan <[email protected]>
    Co-authored-by: Volkan Yazıcı <[email protected]>
---
 .../plugins/processor/GraalVmProcessorTest.java    | 60 +++++++++++++++++++---
 .../processor/PluginProcessorPublicSetterTest.java | 10 ++--
 .../config/plugins/processor/GraalVmProcessor.java | 50 ++++++++++++++----
 .../config/plugins/processor/PluginProcessor.java  | 26 +++++-----
 .../.2.x.x/4225_plugin_processor_messages.xml      | 13 +++++
 .../antora/modules/ROOT/pages/manual/plugins.adoc  |  6 +--
 6 files changed, 127 insertions(+), 38 deletions(-)

diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/GraalVmProcessorTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/GraalVmProcessorTest.java
index 4605fcb70b..f46150f4a3 100644
--- 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/GraalVmProcessorTest.java
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/GraalVmProcessorTest.java
@@ -222,6 +222,7 @@ class GraalVmProcessorTest {
         assertThat(diagnostics).hasSize(1);
         // The warning message should contain the information about the 
missing groupId and artifactId arguments
         assertThat(diagnostics.get(0))
+                .startsWith("[Log4j] ")
                 .contains(
                         "recommended",
                         "-A" + GraalVmProcessor.GROUP_ID + "=<groupId>",
@@ -239,8 +240,56 @@ class GraalVmProcessorTest {
                 .exists();
     }
 
+    @Test
+    void noteEmittedByDefaultWithLog4jPrefix(@TempDir Path outputDir) throws 
Exception {
+        List<Diagnostic<? extends JavaFileObject>> diagnostics =
+                generateDiagnostics(sourceDir, GROUP_ID, ARTIFACT_ID, 
outputDir);
+
+        assertThat(diagnostics)
+                .anyMatch(diagnostic -> diagnostic.getKind() == 
Diagnostic.Kind.NOTE
+                        && diagnostic
+                                .getMessage(Locale.ROOT)
+                                .startsWith("[Log4j] GraalVmProcessor: writing 
GraalVM metadata"));
+    }
+
+    @Test
+    void notesSuppressedWithoutAffectingMetadataGeneration(@TempDir Path 
outputDir) throws Exception {
+        List<Diagnostic<? extends JavaFileObject>> diagnostics = 
generateDiagnostics(
+                sourceDir,
+                GROUP_ID,
+                ARTIFACT_ID,
+                outputDir,
+                "-A" + PluginProcessor.MIN_ALLOWED_MESSAGE_KIND_OPTION + 
"=warning");
+
+        assertThat(diagnostics)
+                .noneMatch(diagnostic -> diagnostic.getKind() == 
Diagnostic.Kind.NOTE
+                        && 
diagnostic.getMessage(Locale.ROOT).contains("writing GraalVM metadata"));
+        
assertThat(outputDir.resolve("META-INF/native-image/log4j-generated/groupId/artifactId/reflect-config.json"))
+                .exists();
+    }
+
     private static List<String> generateDescriptor(
-            Path sourceDir, @Nullable String groupId, @Nullable String 
artifactId, Path outputDir) throws Exception {
+            Path sourceDir,
+            @Nullable String groupId,
+            @Nullable String artifactId,
+            Path outputDir,
+            String... extraOptions)
+            throws Exception {
+        return generateDiagnostics(sourceDir, groupId, artifactId, outputDir, 
extraOptions).stream()
+                .filter(d -> d.getKind() != Diagnostic.Kind.NOTE)
+                .map(d -> d.getMessage(Locale.ROOT))
+                // This message appears when the test runs on JDK 8
+                .filter(m -> !"unknown enum constant 
java.lang.annotation.ElementType.MODULE".equals(m))
+                .collect(Collectors.toList());
+    }
+
+    private static List<Diagnostic<? extends JavaFileObject>> 
generateDiagnostics(
+            Path sourceDir,
+            @Nullable String groupId,
+            @Nullable String artifactId,
+            Path outputDir,
+            String... extraOptions)
+            throws Exception {
         // Instantiate the tooling
         final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
         final StandardJavaFileManager fileManager = 
compiler.getStandardFileManager(null, Locale.ROOT, UTF_8);
@@ -267,6 +316,7 @@ class GraalVmProcessorTest {
         if (artifactId != null) {
             options.add("-A" + GraalVmProcessor.ARTIFACT_ID + "=" + 
artifactId);
         }
+        options.addAll(asList(extraOptions));
 
         // Compile the sources
         final DiagnosticCollector<JavaFileObject> diagnosticCollector = new 
DiagnosticCollector<>();
@@ -274,12 +324,6 @@ class GraalVmProcessorTest {
                 compiler.getTask(null, fileManager, diagnosticCollector, 
options, null, sources);
         task.call();
 
-        // Verify successful compilation
-        return diagnosticCollector.getDiagnostics().stream()
-                .filter(d -> d.getKind() != Diagnostic.Kind.NOTE)
-                .map(d -> d.getMessage(Locale.ROOT))
-                // This message appears when the test runs on JDK 8
-                .filter(m -> !"unknown enum constant 
java.lang.annotation.ElementType.MODULE".equals(m))
-                .collect(Collectors.toList());
+        return diagnosticCollector.getDiagnostics();
     }
 }
diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessorPublicSetterTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessorPublicSetterTest.java
index 2b6a03d1fe..3772cced4d 100644
--- 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessorPublicSetterTest.java
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessorPublicSetterTest.java
@@ -99,7 +99,7 @@ public class PluginProcessorPublicSetterTest {
     void warnWhenPluginBuilderAttributeLacksPublicSetter() {
         assertThat(errorDiagnostics).anyMatch(errorMessage -> errorMessage
                 .getMessage(Locale.ROOT)
-                .contains("The field `attribute` does not have a public 
setter"));
+                .startsWith("[Log4j] The field `attribute` does not have a 
public setter"));
     }
 
     @Test
@@ -117,7 +117,8 @@ public class PluginProcessorPublicSetterTest {
         final List<Diagnostic<? extends JavaFileObject>> noteDiagnostics = 
diagnosticCollector.getDiagnostics().stream()
                 .filter(d -> d.getKind() == Diagnostic.Kind.NOTE)
                 .collect(Collectors.toList());
-        assertThat(noteDiagnostics).anyMatch(d -> 
d.getMessage(Locale.ROOT).contains("writing plugin descriptor"));
+        assertThat(noteDiagnostics).anyMatch(d -> d.getMessage(Locale.ROOT)
+                .startsWith("[Log4j] PluginProcessor: writing plugin 
descriptor"));
     }
 
     @Test
@@ -161,6 +162,9 @@ public class PluginProcessorPublicSetterTest {
                         .filter(d -> d.getKind() == Diagnostic.Kind.WARNING)
                         .collect(Collectors.toList());
         assertThat(warningDiagnostics)
-                .anyMatch(d -> 
d.getMessage(Locale.ROOT).contains("unrecognized value `INVALID`"));
+                .anyMatch(d -> d.getMessage(Locale.ROOT)
+                                .startsWith(
+                                        "[Log4j] 
org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor:")
+                        && d.getMessage(Locale.ROOT).contains("unrecognized 
value `INVALID`"));
     }
 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/GraalVmProcessor.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/GraalVmProcessor.java
index 4603ec5ee9..05528f96a9 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/GraalVmProcessor.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/GraalVmProcessor.java
@@ -25,10 +25,10 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.Messager;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.annotation.processing.Processor;
 import javax.annotation.processing.RoundEnvironment;
@@ -71,23 +71,41 @@ import org.jspecify.annotations.Nullable;
     "org.apache.logging.log4j.core.config.plugins.PluginValue",
     "org.apache.logging.log4j.core.config.plugins.PluginVisitorStrategy"
 })
-@SupportedOptions({"log4j.graalvm.groupId", "log4j.graalvm.artifactId"})
+@SupportedOptions({"log4j.graalvm.groupId", "log4j.graalvm.artifactId", 
"log4j.plugin.processor.minAllowedMessageKind"})
 public class GraalVmProcessor extends AbstractProcessor {
 
     static final String GROUP_ID = "log4j.graalvm.groupId";
     static final String ARTIFACT_ID = "log4j.graalvm.artifactId";
     private static final String LOCATION_PREFIX = 
"META-INF/native-image/log4j-generated/";
     private static final String LOCATION_SUFFIX = "/reflect-config.json";
+    private static final String MESSAGE_PREFIX = "[Log4j] ";
     private static final String PROCESSOR_NAME = 
GraalVmProcessor.class.getSimpleName();
 
     private final Map<String, ReachabilityMetadata.Type> reachableTypes = new 
HashMap<>();
     private final List<Element> processedElements = new ArrayList<>();
     private Annotations annotationUtil;
+    private Diagnostic.Kind minAllowedMessageKind = Diagnostic.Kind.NOTE;
 
     @Override
     public synchronized void init(ProcessingEnvironment processingEnv) {
         super.init(processingEnv);
         this.annotationUtil = new Annotations(processingEnv.getElementUtils());
+        final String kindValue = 
processingEnv.getOptions().get(PluginProcessor.MIN_ALLOWED_MESSAGE_KIND_OPTION);
+        if (kindValue != null) {
+            try {
+                minAllowedMessageKind = 
Diagnostic.Kind.valueOf(kindValue.toUpperCase(Locale.ROOT));
+            } catch (final IllegalArgumentException e) {
+                printMessage(
+                        Diagnostic.Kind.WARNING,
+                        String.format(
+                                "%s: unrecognized value `%s` for option `%s`, 
using default `%s`. Valid values: %s",
+                                GraalVmProcessor.class.getName(),
+                                kindValue,
+                                
PluginProcessor.MIN_ALLOWED_MESSAGE_KIND_OPTION,
+                                Diagnostic.Kind.NOTE,
+                                Arrays.toString(Diagnostic.Kind.values())));
+            }
+        }
     }
 
     @Override
@@ -97,7 +115,6 @@ public class GraalVmProcessor extends AbstractProcessor {
 
     @Override
     public boolean process(Set<? extends TypeElement> annotations, 
RoundEnvironment roundEnv) {
-        Messager messager = processingEnv.getMessager();
         for (TypeElement annotation : annotations) {
             Annotations.Type annotationType = 
annotationUtil.classifyAnnotation(annotation);
             for (Element element : 
roundEnv.getElementsAnnotatedWith(annotation)) {
@@ -115,7 +132,7 @@ public class GraalVmProcessor extends AbstractProcessor {
                         processFactory(element);
                         break;
                     case UNKNOWN:
-                        messager.printMessage(
+                        printMessage(
                                 Diagnostic.Kind.WARNING,
                                 String.format(
                                         "The annotation type `%s` is not 
handled by %s", annotation, PROCESSOR_NAME),
@@ -174,7 +191,7 @@ public class GraalVmProcessor extends AbstractProcessor {
                 break;
             default:
                 String msg = String.format("Invalid Log4j parameter element 
`%s`.", element);
-                
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg, element);
+                printMessage(Diagnostic.Kind.ERROR, msg, element);
                 throw new IllegalStateException(msg);
         }
     }
@@ -192,7 +209,7 @@ public class GraalVmProcessor extends AbstractProcessor {
         } catch (IOException e) {
             String message = String.format(
                     "%s: an error occurred while generating reachability 
metadata: %s", PROCESSOR_NAME, e.getMessage());
-            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 
message);
+            printMessage(Diagnostic.Kind.ERROR, message);
             return;
         }
         byte[] data = arrayOutputStream.toByteArray();
@@ -200,8 +217,7 @@ public class GraalVmProcessor extends AbstractProcessor {
         Map<String, String> options = processingEnv.getOptions();
         String reachabilityMetadataPath = getReachabilityMetadataPath(
                 options.get(GROUP_ID), options.get(ARTIFACT_ID), 
Integer.toHexString(Arrays.hashCode(data)));
-        Messager messager = processingEnv.getMessager();
-        messager.printMessage(
+        printMessage(
                 Diagnostic.Kind.NOTE,
                 String.format(
                         "%s: writing GraalVM metadata for %d Java classes to 
`%s`.",
@@ -218,7 +234,7 @@ public class GraalVmProcessor extends AbstractProcessor {
         } catch (IOException e) {
             String message = String.format(
                     "%s: unable to write reachability metadata to file `%s`", 
PROCESSOR_NAME, reachabilityMetadataPath);
-            messager.printMessage(Diagnostic.Kind.ERROR, message);
+            printMessage(Diagnostic.Kind.ERROR, message);
             throw new IllegalArgumentException(message, e);
         }
     }
@@ -243,7 +259,7 @@ public class GraalVmProcessor extends AbstractProcessor {
                             + "  -A%2$s=<groupId>%n"
                             + "  -A%3$s=<artifactId>%n",
                     PROCESSOR_NAME, GROUP_ID, ARTIFACT_ID);
-            processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, 
message);
+            printMessage(Diagnostic.Kind.WARNING, message);
             return LOCATION_PREFIX + fallbackFolderName + LOCATION_SUFFIX;
         }
         return LOCATION_PREFIX + groupId + '/' + artifactId + LOCATION_SUFFIX;
@@ -273,10 +289,22 @@ public class GraalVmProcessor extends AbstractProcessor {
         String msg = String.format(
                 "Unexpected type of element `%s`: expecting `%s` but found 
`%s`",
                 element, type.getName(), element.getClass().getName());
-        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg, 
element);
+        printMessage(Diagnostic.Kind.ERROR, msg, element);
         throw new IllegalStateException(msg);
     }
 
+    private void printMessage(final Diagnostic.Kind kind, final String 
message) {
+        if (kind.ordinal() <= minAllowedMessageKind.ordinal()) {
+            processingEnv.getMessager().printMessage(kind, MESSAGE_PREFIX + 
message);
+        }
+    }
+
+    private void printMessage(final Diagnostic.Kind kind, final String 
message, final Element element) {
+        if (kind.ordinal() <= minAllowedMessageKind.ordinal()) {
+            processingEnv.getMessager().printMessage(kind, MESSAGE_PREFIX + 
message, element);
+        }
+    }
+
     /**
      * Returns the fully qualified name of a type.
      *
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessor.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessor.java
index 94557a7ddb..51b7e09109 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessor.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessor.java
@@ -69,6 +69,8 @@ public class PluginProcessor extends AbstractProcessor {
 
     private static final Element[] EMPTY_ELEMENT_ARRAY = {};
 
+    private static final String MESSAGE_PREFIX = "[Log4j] ";
+
     private static final String SUPPRESS_WARNING_PUBLIC_SETTER_STRING = 
"log4j.public.setter";
 
     /**
@@ -105,17 +107,15 @@ public class PluginProcessor extends AbstractProcessor {
             try {
                 minAllowedMessageKind = 
Diagnostic.Kind.valueOf(kindValue.toUpperCase(Locale.ROOT));
             } catch (final IllegalArgumentException e) {
-                processingEnv
-                        .getMessager()
-                        .printMessage(
-                                Diagnostic.Kind.WARNING,
-                                String.format(
-                                        "%s: unrecognized value `%s` for 
option `%s`, using default `%s`. Valid values: %s",
-                                        PluginProcessor.class.getName(),
-                                        kindValue,
-                                        MIN_ALLOWED_MESSAGE_KIND_OPTION,
-                                        Diagnostic.Kind.NOTE,
-                                        
Arrays.toString(Diagnostic.Kind.values())));
+                printMessage(
+                        Diagnostic.Kind.WARNING,
+                        String.format(
+                                "%s: unrecognized value `%s` for option `%s`, 
using default `%s`. Valid values: %s",
+                                PluginProcessor.class.getName(),
+                                kindValue,
+                                MIN_ALLOWED_MESSAGE_KIND_OPTION,
+                                Diagnostic.Kind.NOTE,
+                                Arrays.toString(Diagnostic.Kind.values())));
             }
         }
     }
@@ -134,7 +134,7 @@ public class PluginProcessor extends AbstractProcessor {
      */
     private void printMessage(final Diagnostic.Kind kind, final String 
message) {
         if (kind.ordinal() <= minAllowedMessageKind.ordinal()) {
-            processingEnv.getMessager().printMessage(kind, message);
+            processingEnv.getMessager().printMessage(kind, MESSAGE_PREFIX + 
message);
         }
     }
 
@@ -144,7 +144,7 @@ public class PluginProcessor extends AbstractProcessor {
      */
     private void printMessage(final Diagnostic.Kind kind, final String 
message, final Element element) {
         if (kind.ordinal() <= minAllowedMessageKind.ordinal()) {
-            processingEnv.getMessager().printMessage(kind, message, element);
+            processingEnv.getMessager().printMessage(kind, MESSAGE_PREFIX + 
message, element);
         }
     }
 
diff --git a/src/changelog/.2.x.x/4225_plugin_processor_messages.xml 
b/src/changelog/.2.x.x/4225_plugin_processor_messages.xml
new file mode 100644
index 0000000000..f52ac661a7
--- /dev/null
+++ b/src/changelog/.2.x.x/4225_plugin_processor_messages.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns="https://logging.apache.org/xml/ns";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="
+           https://logging.apache.org/xml/ns
+           https://logging.apache.org/xml/ns/log4j-changelog-0.xsd";
+       type="changed">
+  <issue id="4225" 
link="https://github.com/apache/logging-log4j2/issues/4225"/>
+  <issue id="4228" link="https://github.com/apache/logging-log4j2/pull/4228"/>
+  <description format="asciidoc">
+    Allow `log4j.plugin.processor.minAllowedMessageKind` to filter 
`GraalVmProcessor` diagnostics and prefix all plugin processor messages with 
`[Log4j]`.
+  </description>
+</entry>
diff --git a/src/site/antora/modules/ROOT/pages/manual/plugins.adoc 
b/src/site/antora/modules/ROOT/pages/manual/plugins.adoc
index f8d6b5ff4b..a647ef5024 100644
--- a/src/site/antora/modules/ROOT/pages/manual/plugins.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/plugins.adoc
@@ -215,13 +215,13 @@ The `GraalVmProcessor` requires your project's `groupId` 
and `artifactId` to cor
 Provide these values to the processor using the `log4j.graalvm.groupId` and 
`log4j.graalvm.artifactId` annotation processor options.
 ====
 
-.Suppressing notes from `PluginProcessor` in strict build environments
+.Suppressing annotation processor notes in strict build environments
 [%collapsible]
 ====
 Some build environments treat all compiler notes or warnings as errors (e.g., 
Maven with `-Werror` or Gradle with `options.compilerArgs << '-Werror'`).
-By default, `PluginProcessor` emits a `NOTE`-level diagnostic when it writes 
the plugin descriptor, which can cause the build to fail in those environments.
+By default, `PluginProcessor` and `GraalVmProcessor` emit `NOTE`-level 
diagnostics when they write their descriptors, which can cause the build to 
fail in those environments.
 To suppress these informational notes, pass the 
`log4j.plugin.processor.minAllowedMessageKind` annotation processor option with 
a value of `WARNING` or `ERROR`.
-This instructs the processor to only emit diagnostics at or above the 
specified severity, silencing routine notes while preserving genuine warnings 
and errors.
+This instructs aforementioned processors to only emit diagnostics at or above 
the specified severity, silencing routine notes while preserving genuine 
warnings and errors.
 
 Accepted values (case-insensitive): `NOTE` (default), `WARNING`, 
`MANDATORY_WARNING`, `ERROR`, `OTHER`.
 

Reply via email to