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:12 UTC
(logging-log4j2) branch fix/2.x/3796_annotated-array-parameters created (now 91efb4ccf2)
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a change to branch fix/2.x/3796_annotated-array-parameters
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
at 91efb4ccf2 fix: Fix Java type for annotated array parameters
This branch includes the following new commits:
new 91efb4ccf2 fix: Fix Java type for annotated array parameters
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(logging-log4j2) 01/01: fix: Fix Java type for annotated array parameters
Posted by pk...@apache.org.
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>