You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2025/07/01 13:39:13 UTC
(logging-log4j2) 01/01: fix: Fix Java type for annotated array parameters
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch fix/2.x/3796_annotated-array-parameters
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 91efb4ccf25944473e05d0074a4102fc06a21386
Author: Piotr P. Karwasz <pk...@apache.org>
AuthorDate: Tue Jul 1 15:38:26 2025 +0200
fix: Fix Java type for annotated array parameters
This update fixes the GraalVM reachability metadata generation for methods with annotated array parameters, such as `@Nullable String[]`.
Previously, the code computed the fully qualified class name for the parameter using the **raw** type, which retained the annotations (e.g., `@org.jspecify.annotations.Nullable java.lang.String`). This resulted in incorrect metadata that was ignored by GraalVM.
The issue is resolved by transforming the `DeclaredType` into a `TypeElement`, effectively removing any annotations, and then calling `getQualifiedName()` to correctly generate the fully qualified class name without annotations.
---
.../plugins/processor/GraalVmProcessorTest.java | 22 +++++++++--
.../GraalVmProcessorTest/java/FakeConverter.java | 46 ++++++++++++++++++++++
.../config/plugins/processor/GraalVmProcessor.java | 4 +-
.../.2.x.x/3796_annotated-array-parameters.xml | 12 ++++++
4 files changed, 79 insertions(+), 5 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 9bdbcad8dd..fdf39657bc 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
@@ -103,6 +103,18 @@ class GraalVmProcessorTest {
private static final Object FAKE_CONSTRAINT_VALIDATOR = onlyNoArgsConstructor(FAKE_CONSTRAINT_VALIDATOR_NAME);
private static final String FAKE_PLUGIN_VISITOR_NAME = "example.FakeAnnotations$FakePluginVisitor";
private static final Object FAKE_PLUGIN_VISITOR = onlyNoArgsConstructor(FAKE_PLUGIN_VISITOR_NAME);
+ private static final String FAKE_CONVERTER_NAME = "example.FakeConverter";
+ private static final Object FAKE_CONVERTER = asMap(
+ "name",
+ FAKE_CONVERTER_NAME,
+ "methods",
+ singletonList(asMap(
+ "name",
+ "newInstance",
+ "parameterTypes",
+ asList("org.apache.logging.log4j.core.config.Configuration", "java.lang.String[]"))),
+ "fields",
+ emptyList());
private static final String GROUP_ID = "groupId";
private static final String ARTIFACT_ID = "artifactId";
@@ -155,7 +167,8 @@ class GraalVmProcessorTest {
Arguments.of(FAKE_PLUGIN_BUILDER_NAME, FAKE_PLUGIN_BUILDER),
Arguments.of(FAKE_PLUGIN_NESTED_NAME, FAKE_PLUGIN_NESTED),
Arguments.of(FAKE_CONSTRAINT_VALIDATOR_NAME, FAKE_CONSTRAINT_VALIDATOR),
- Arguments.of(FAKE_PLUGIN_VISITOR_NAME, FAKE_PLUGIN_VISITOR));
+ Arguments.of(FAKE_PLUGIN_VISITOR_NAME, FAKE_PLUGIN_VISITOR),
+ Arguments.of(FAKE_CONVERTER_NAME, FAKE_CONVERTER));
}
@ParameterizedTest
@@ -168,7 +181,9 @@ class GraalVmProcessorTest {
assertThatJson(reachabilityMetadata)
.inPath(String.format("$[?(@.name == '%s')]", className))
.isArray()
- .contains(json(expectedJson));
+ .hasSize(1)
+ .first()
+ .isEqualTo(json(expectedJson));
}
static Stream<Arguments> reachabilityMetadataPath() {
@@ -214,7 +229,7 @@ class GraalVmProcessorTest {
}
// 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("62162090"));
+ assertThat(reachabilityMetadataFolders).hasSize(1).containsExactly(path.resolve("e51e0522"));
assertThat(reachabilityMetadataFolders.get(0).resolve("reflect-config.json"))
.as("Reachability metadata file")
.exists();
@@ -250,7 +265,6 @@ class GraalVmProcessorTest {
}
// Compile the sources
- final Path descriptorFilePath = outputDir.resolve("plugins.xml");
final DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<>();
final JavaCompiler.CompilationTask task =
compiler.getTask(null, fileManager, diagnosticCollector, options, null, sources);
diff --git a/log4j-core-test/src/test/resources/GraalVmProcessorTest/java/FakeConverter.java b/log4j-core-test/src/test/resources/GraalVmProcessorTest/java/FakeConverter.java
new file mode 100644
index 0000000000..0b15cb4ecc
--- /dev/null
+++ b/log4j-core-test/src/test/resources/GraalVmProcessorTest/java/FakeConverter.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.pattern.ConverterKeys;
+import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
+import org.apache.logging.log4j.core.pattern.PatternConverter;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+
+@NullMarked
+@Plugin(name = "FakePatternConverter", category = PatternConverter.CATEGORY)
+@ConverterKeys({"f", "fake"})
+public final class FakeConverter extends LogEventPatternConverter {
+
+ private FakeConverter(@Nullable final Configuration config, @Nullable final String[] options) {
+ super("Fake", "fake");
+ }
+
+ public static FakeConverter newInstance(
+ @Nullable final Configuration config, @Nullable final String[] options) {
+ return new FakeConverter(config, options);
+ }
+
+ @Override
+ public void format(LogEvent event, StringBuilder toAppendTo) {
+ toAppendTo.append("FakeConverter: ").append(event.getMessage().getFormattedMessage());
+ }
+}
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 e6178f2a17..a5ba7ba61c 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
@@ -300,7 +300,9 @@ public class GraalVmProcessor extends AbstractProcessor {
@Override
public @Nullable String visitDeclared(final DeclaredType t, final Void unused) {
- return processingEnv.getTypeUtils().erasure(t).toString();
+ return safeCast(t.asElement(), TypeElement.class)
+ .getQualifiedName()
+ .toString();
}
},
null);
diff --git a/src/changelog/.2.x.x/3796_annotated-array-parameters.xml b/src/changelog/.2.x.x/3796_annotated-array-parameters.xml
new file mode 100644
index 0000000000..5be57fe641
--- /dev/null
+++ b/src/changelog/.2.x.x/3796_annotated-array-parameters.xml
@@ -0,0 +1,12 @@
+<?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="fixed">
+ <issue id="3796" link="https://github.com/apache/logging-log4j2/issues/3796"/>
+ <description format="asciidoc">
+ Fix GraalVM reachability metadata generation for methods with annotated array type parameters, such as `@Nullable String[]`.
+ </description>
+</entry>