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

jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/main by this push:
     new c071c5dd6b Register BeanDescription.findJsonValueAccessor for 
reflection
c071c5dd6b is described below

commit c071c5dd6b0f1e124e33d765a7f13a85c9cbeb70
Author: James Netherton <[email protected]>
AuthorDate: Mon Sep 21 11:15:24 2026 +0100

    Register BeanDescription.findJsonValueAccessor for reflection
    
    Swagger ModelResolver looks the method up with a method name that the native
    image builder cannot fold, so in native mode @JsonValue types were rendered 
as
    object schemas and every resolved model logged a WARN and an ERROR.
    
    Fixes #9195
    
    Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
---
 .../deployment/SupportSwaggerProcessor.java        | 13 ++++++
 .../component/openapijava/it/OpenApiRoutes.java    | 19 +++++++++
 .../openapijava/it/model/JsonValueForm.java        | 47 ++++++++++++++++++++++
 .../openapijava/it/model/JsonValueFormWrapper.java | 35 ++++++++++++++++
 .../component/openapijava/it/v3/OpenApiV3Test.java | 16 ++++++++
 5 files changed, 130 insertions(+)

diff --git 
a/extensions-support/swagger/deployment/src/main/java/org/apache/camel/quarkus/support/swagger/deployment/SupportSwaggerProcessor.java
 
b/extensions-support/swagger/deployment/src/main/java/org/apache/camel/quarkus/support/swagger/deployment/SupportSwaggerProcessor.java
index 3aba033161..815b8a57ee 100644
--- 
a/extensions-support/swagger/deployment/src/main/java/org/apache/camel/quarkus/support/swagger/deployment/SupportSwaggerProcessor.java
+++ 
b/extensions-support/swagger/deployment/src/main/java/org/apache/camel/quarkus/support/swagger/deployment/SupportSwaggerProcessor.java
@@ -19,11 +19,14 @@ package org.apache.camel.quarkus.support.swagger.deployment;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import com.fasterxml.jackson.databind.BeanDescription;
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
 import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
 import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ReflectiveMethodBuildItem;
+import io.swagger.v3.core.jackson.ModelResolver;
 import io.swagger.v3.oas.models.media.Schema;
 import org.jboss.jandex.ClassInfo;
 
@@ -61,4 +64,14 @@ class SupportSwaggerProcessor {
                 .methods()
                 .build());
     }
+
+    @BuildStep
+    ReflectiveMethodBuildItem jsonValueAccessorMethod() {
+        // ModelResolver.findJsonValueType looks the method up with a method 
name that the image builder cannot fold
+        return new ReflectiveMethodBuildItem(
+                ModelResolver.class.getName() + " requires reflective access 
to it",
+                BeanDescription.class.getName(),
+                "findJsonValueAccessor",
+                new String[0]);
+    }
 }
diff --git 
a/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiRoutes.java
 
b/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiRoutes.java
index e317835f6f..b41b41df94 100644
--- 
a/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiRoutes.java
+++ 
b/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiRoutes.java
@@ -29,6 +29,7 @@ import org.apache.camel.model.rest.RestParamType;
 import 
org.apache.camel.quarkus.component.openapijava.it.model.AllOfFormWrapper;
 import 
org.apache.camel.quarkus.component.openapijava.it.model.AnyOfFormWrapper;
 import org.apache.camel.quarkus.component.openapijava.it.model.Fruit;
+import 
org.apache.camel.quarkus.component.openapijava.it.model.JsonValueFormWrapper;
 import 
org.apache.camel.quarkus.component.openapijava.it.model.OneOfFormWrapper;
 
 @ApplicationScoped
@@ -265,6 +266,21 @@ public class OpenApiRoutes extends RouteBuilder {
 
                 .to("seda:res");
 
+        rest("/form")
+                .post("/jsonValue")
+                .tag("JsonValue")
+                .bindingMode(RestBindingMode.json)
+                .description("JsonValue rest service")
+
+                .consumes("application/json")
+                .produces("application/json")
+                .type(JsonValueFormWrapper.class)
+                .responseMessage()
+                .code(200).message("Ok")
+                .endResponseMessage()
+
+                .to("direct:jsonValueForm");
+
         rest("/form")
                 .post("/anyOf")
                 .tag("AnyOf")
@@ -280,6 +296,9 @@ public class OpenApiRoutes extends RouteBuilder {
 
                 .to("seda:res");
 
+        from("direct:jsonValueForm")
+                .setBody(constant("{\"result\": \"Ok\"}"));
+
         from("direct:fruits")
                 .setBody().constant(getFruits())
                 .marshal().json();
diff --git 
a/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/model/JsonValueForm.java
 
b/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/model/JsonValueForm.java
new file mode 100644
index 0000000000..a67703a23e
--- /dev/null
+++ 
b/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/model/JsonValueForm.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.apache.camel.quarkus.component.openapijava.it.model;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+/**
+ * A class that Jackson serializes as a simple string via the {@link 
JsonValue} annotated accessor.
+ */
+@RegisterForReflection
+public class JsonValueForm {
+
+    String code;
+    String description;
+
+    @JsonValue
+    public String getCode() {
+        return this.code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getDescription() {
+        return this.description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}
diff --git 
a/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/model/JsonValueFormWrapper.java
 
b/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/model/JsonValueFormWrapper.java
new file mode 100644
index 0000000000..b1f53cb7d2
--- /dev/null
+++ 
b/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/model/JsonValueFormWrapper.java
@@ -0,0 +1,35 @@
+/*
+ * 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 org.apache.camel.quarkus.component.openapijava.it.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection
+public class JsonValueFormWrapper {
+
+    @JsonProperty("form")
+    JsonValueForm form;
+
+    public JsonValueForm getForm() {
+        return this.form;
+    }
+
+    public void setForm(JsonValueForm form) {
+        this.form = form;
+    }
+}
diff --git 
a/integration-tests/openapi-java/src/test/java/org/apache/camel/quarkus/component/openapijava/it/v3/OpenApiV3Test.java
 
b/integration-tests/openapi-java/src/test/java/org/apache/camel/quarkus/component/openapijava/it/v3/OpenApiV3Test.java
index 9596590bab..3ae8806826 100644
--- 
a/integration-tests/openapi-java/src/test/java/org/apache/camel/quarkus/component/openapijava/it/v3/OpenApiV3Test.java
+++ 
b/integration-tests/openapi-java/src/test/java/org/apache/camel/quarkus/component/openapijava/it/v3/OpenApiV3Test.java
@@ -375,6 +375,22 @@ public class OpenApiV3Test {
                         is("#/components/schemas/AnyOfForm"));
     }
 
+    @ParameterizedTest
+    @EnumSource(OpenApiContentType.class)
+    public void openApiJsonValue(OpenApiContentType contentType) {
+        RestAssured.given()
+                .header("Accept", contentType.getMimeType())
+                .get("/openapi")
+                .then()
+                .contentType(ContentType.JSON)
+                .statusCode(200)
+                .body(
+                        "components.schemas.JsonValueFormWrapper.type", 
is("object"),
+                        // The @JsonValue accessor determines the schema, so 
the remaining bean properties must not leak
+                        
"components.schemas.JsonValueFormWrapper.properties.form.type", is("string"),
+                        "components.schemas", not(hasKey("JsonValueForm")));
+    }
+
     @ParameterizedTest
     @EnumSource(OpenApiContentType.class)
     public void arrayTypes(OpenApiContentType contentType) {

Reply via email to