From 5d305747f98242787c3ed4d0588af2558ed89139 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Thu, 11 Dec 2025 20:38:20 +0100 Subject: [PATCH 1/2] Use binary names in `GraalVmProcessor` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `GraalVmProcessor` currently emits canonical type names (JLS §6.7) for parameter types in the GraalVM reachability metadata. However, testing shows that GraalVM expects **binary names** (JLS §13.1) for reference types. For example: * Canonical: `org.apache.logging.log4j.core.Filter.Result` * Required (binary): `org.apache.logging.log4j.core.Filter$Result` For array types, GraalVM accepts two forms: * The JVM descriptor form: `[L;` * The Java-like form: `[]` This PR updates the processor to use binary names and emits the simpler Java-like syntax for arrays. --- .../processor/GraalVmProcessorTest.java | 8 +++-- .../GraalVmProcessorTest/java/FakePlugin.java | 11 ++++++- .../plugins/processor/GraalVmProcessor.java | 32 ++----------------- .../.2.x.x/3871_graalvm_binary_name.xml | 13 ++++++++ 4 files changed, 32 insertions(+), 32 deletions(-) create mode 100644 src/changelog/.2.x.x/3871_graalvm_binary_name.xml 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 957bb3228cd..4605fcb70b1 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 @@ -79,7 +79,9 @@ class GraalVmProcessorTest { "org.apache.logging.log4j.core.config.Configuration", "org.apache.logging.log4j.core.config.Node", "org.apache.logging.log4j.core.LoggerContext", - "java.lang.String"))), + "java.lang.String", + "org.apache.logging.log4j.core.Filter$Result", + "org.apache.logging.log4j.core.Filter[]"))), "fields", emptyList()); private static final String FAKE_PLUGIN_BUILDER_NAME = FAKE_PLUGIN_NAME + "$Builder"; @@ -93,9 +95,11 @@ class GraalVmProcessorTest { asMap("name", "attribute"), asMap("name", "attributeWithoutPublicSetterButWithSuppressAnnotation"), asMap("name", "config"), + asMap("name", "filters"), asMap("name", "layout"), asMap("name", "loggerContext"), asMap("name", "node"), + asMap("name", "onMatch"), asMap("name", "value"))); private static final String FAKE_PLUGIN_NESTED_NAME = FAKE_PLUGIN_NAME + "$Nested"; private static final Object FAKE_PLUGIN_NESTED = onlyNoArgsConstructor(FAKE_PLUGIN_NESTED_NAME); @@ -229,7 +233,7 @@ void whenNoGroupIdAndArtifactId_thenWarningIsPrinted(@TempDir(cleanup = CleanupM } // The generated folder name should be deterministic and based solely on the descriptor content. // If the descriptor changes, this test and the expected folder name must be updated accordingly. - assertThat(reachabilityMetadataFolders).hasSize(1).containsExactly(path.resolve("72c240aa")); + assertThat(reachabilityMetadataFolders).hasSize(1).containsExactly(path.resolve("791e18c8")); assertThat(reachabilityMetadataFolders.get(0).resolve("reflect-config.json")) .as("Reachability metadata file") .exists(); diff --git a/log4j-core-test/src/test/resources/GraalVmProcessorTest/java/FakePlugin.java b/log4j-core-test/src/test/resources/GraalVmProcessorTest/java/FakePlugin.java index 90b872c0a31..40728b0fc54 100644 --- a/log4j-core-test/src/test/resources/GraalVmProcessorTest/java/FakePlugin.java +++ b/log4j-core-test/src/test/resources/GraalVmProcessorTest/java/FakePlugin.java @@ -17,6 +17,7 @@ package example; import java.io.Serializable; +import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.Configuration; @@ -49,7 +50,9 @@ public static FakePlugin newPlugin( @PluginConfiguration Configuration config, @PluginNode Node node, @PluginLoggerContext LoggerContext loggerContext, - @PluginValue("value") String value) { + @PluginValue("value") String value, + @PluginValue("onMatch") Filter.Result onMatch, + @PluginElement("filters") Filter[] filters) { return null; } @@ -82,6 +85,12 @@ public static class Builder implements org.apache.logging.log4j.core.util.Builde @PluginValue("value") private String value; + @PluginValue("onMatch") + private Filter.Result onMatch; + + @PluginElement("filters") + private Filter[] filters; + @Override public FakePlugin build() { return null; 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 a5ba7ba61c5..4603ec5ee91 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 @@ -36,16 +36,13 @@ import javax.annotation.processing.SupportedOptions; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; -import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.ArrayType; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.SimpleElementVisitor8; import javax.lang.model.util.SimpleTypeVisitor8; import javax.tools.Diagnostic; import javax.tools.StandardLocation; @@ -300,9 +297,7 @@ public String visitArray(final ArrayType t, @Nullable Void unused) { @Override public @Nullable String visitDeclared(final DeclaredType t, final Void unused) { - return safeCast(t.asElement(), TypeElement.class) - .getQualifiedName() - .toString(); + return GraalVmProcessor.this.toString(safeCast(t.asElement(), TypeElement.class)); } }, null); @@ -313,28 +308,7 @@ public String visitArray(final ArrayType t, @Nullable Void unused) { * * @param element A Java language element. */ - private String toString(Element element) { - return element.accept( - new SimpleElementVisitor8() { - @Override - public String visitPackage(PackageElement e, @Nullable Void unused) { - return e.getQualifiedName().toString(); - } - - @Override - public String visitType(TypeElement e, @Nullable Void unused) { - Element parent = e.getEnclosingElement(); - String separator = parent.getKind() == ElementKind.PACKAGE ? "." : "$"; - return visit(parent, unused) - + separator - + e.getSimpleName().toString(); - } - - @Override - protected String defaultAction(Element e, @Nullable Void unused) { - return ""; - } - }, - null); + private String toString(TypeElement element) { + return processingEnv.getElementUtils().getBinaryName(element).toString(); } } diff --git a/src/changelog/.2.x.x/3871_graalvm_binary_name.xml b/src/changelog/.2.x.x/3871_graalvm_binary_name.xml new file mode 100644 index 00000000000..be3cda5fab2 --- /dev/null +++ b/src/changelog/.2.x.x/3871_graalvm_binary_name.xml @@ -0,0 +1,13 @@ + + + + + + Fix GraalVM metadata for nested classes to use binary names instead of canonical names. + + From 38c72b2590ac819c3e3d11a61b19531d9ac9953a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Mon, 15 Dec 2025 09:56:33 +0100 Subject: [PATCH 2/2] Fix changelog entry type --- src/changelog/.2.x.x/3871_graalvm_binary_name.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/changelog/.2.x.x/3871_graalvm_binary_name.xml b/src/changelog/.2.x.x/3871_graalvm_binary_name.xml index be3cda5fab2..a6a5e8c2573 100644 --- a/src/changelog/.2.x.x/3871_graalvm_binary_name.xml +++ b/src/changelog/.2.x.x/3871_graalvm_binary_name.xml @@ -4,7 +4,7 @@ xsi:schemaLocation=" https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd" - type="removed"> + type="fixed">