This is an automated email from the ASF dual-hosted git repository.
pkarwasz 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 7da8450629 fix: Fix Java type for annotated array parameters (#3797)
7da8450629 is described below
commit 7da84506296b6cd836475e27ce85404a28a3d5ee
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Thu Jul 3 16:55:32 2025 +0200
fix: Fix Java type for annotated array parameters (#3797)
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 | 24 +++++++++--
.../GraalVmProcessorTest/java/FakeConverter.java | 46 ++++++++++++++++++++++
.../config/plugins/processor/GraalVmProcessor.java | 4 +-
.../.2.x.x/3796_annotated-array-parameters.xml | 12 ++++++
4 files changed, 81 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..957bb3228c 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("72c240aa"));
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);
@@ -260,6 +274,8 @@ class GraalVmProcessorTest {
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());
}
}
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>