diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java index a2187966147cf4..a92e88117b6c8e 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java @@ -66,6 +66,7 @@ import io.quarkus.resteasy.reactive.spi.ExceptionMapperBuildItem; import io.quarkus.resteasy.reactive.spi.MessageBodyReaderBuildItem; import io.quarkus.resteasy.reactive.spi.MessageBodyWriterBuildItem; +import io.quarkus.vertx.deployment.ReinitializeVertxJsonBuildItem; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; @@ -100,6 +101,11 @@ ResteasyReactiveJacksonProviderDefinedBuildItem jacksonRegistered() { return new ResteasyReactiveJacksonProviderDefinedBuildItem(); } + @BuildStep + ReinitializeVertxJsonBuildItem vertxJson() { + return new ReinitializeVertxJsonBuildItem(); + } + @BuildStep ExceptionMapperBuildItem exceptionMappers() { return new ExceptionMapperBuildItem(DefaultMismatchedInputException.class.getName(), diff --git a/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/main/java/io/quarkus/rest/client/reactive/jackson/deployment/RestClientReactiveJacksonProcessor.java b/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/main/java/io/quarkus/rest/client/reactive/jackson/deployment/RestClientReactiveJacksonProcessor.java index 12fe28143cc6e7..68a80e1f0e0a55 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/main/java/io/quarkus/rest/client/reactive/jackson/deployment/RestClientReactiveJacksonProcessor.java +++ b/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/main/java/io/quarkus/rest/client/reactive/jackson/deployment/RestClientReactiveJacksonProcessor.java @@ -23,6 +23,7 @@ import io.quarkus.resteasy.reactive.jackson.runtime.serialisers.vertx.VertxJsonObjectBasicMessageBodyWriter; import io.quarkus.resteasy.reactive.spi.MessageBodyReaderBuildItem; import io.quarkus.resteasy.reactive.spi.MessageBodyWriterBuildItem; +import io.quarkus.vertx.deployment.ReinitializeVertxJsonBuildItem; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; @@ -37,6 +38,11 @@ void feature(BuildProducer features) { features.produce(new FeatureBuildItem(REST_CLIENT_REACTIVE_JACKSON)); } + @BuildStep + ReinitializeVertxJsonBuildItem vertxJson() { + return new ReinitializeVertxJsonBuildItem(); + } + @BuildStep void additionalProviders( List jacksonProviderDefined, diff --git a/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/ReinitializeVertxJsonBuildItem.java b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/ReinitializeVertxJsonBuildItem.java new file mode 100644 index 00000000000000..b6b4c697ce7d49 --- /dev/null +++ b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/ReinitializeVertxJsonBuildItem.java @@ -0,0 +1,9 @@ +package io.quarkus.vertx.deployment; + +import io.quarkus.builder.item.MultiBuildItem; + +/** + * Marker build item used to force the re-initialization of Vert.x JSON handling in native-image + */ +public final class ReinitializeVertxJsonBuildItem extends MultiBuildItem { +} diff --git a/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/VertxJsonProcessor.java b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/VertxJsonProcessor.java new file mode 100644 index 00000000000000..cbecc141c135ee --- /dev/null +++ b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/VertxJsonProcessor.java @@ -0,0 +1,27 @@ +package io.quarkus.vertx.deployment; + +import java.util.List; + +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem; +import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; +import io.vertx.core.spi.JsonFactory; + +public class VertxJsonProcessor { + + @BuildStep + void nativeSupport(List reinitializeVertxJson, + BuildProducer runtimeReinitializedClassProducer, + BuildProducer serviceProviderBuildItemBuildProducer) { + if (reinitializeVertxJson.isEmpty()) { + return; + } + runtimeReinitializedClassProducer + .produce(new RuntimeReinitializedClassBuildItem(io.vertx.core.json.Json.class.getName())); + runtimeReinitializedClassProducer + .produce(new RuntimeReinitializedClassBuildItem("io.quarkus.vertx.runtime.jackson.QuarkusJacksonJsonCodec")); + serviceProviderBuildItemBuildProducer + .produce(ServiceProviderBuildItem.allProvidersFromClassPath(JsonFactory.class.getName())); + } +} diff --git a/integration-tests/resteasy-reactive-kotlin/standard/pom.xml b/integration-tests/resteasy-reactive-kotlin/standard/pom.xml index bf8df26dd43540..758d622b759c33 100644 --- a/integration-tests/resteasy-reactive-kotlin/standard/pom.xml +++ b/integration-tests/resteasy-reactive-kotlin/standard/pom.xml @@ -275,12 +275,18 @@ maven-surefire-plugin false + + prod + maven-failsafe-plugin false + + prod + diff --git a/integration-tests/resteasy-reactive-kotlin/standard/src/main/kotlin/io/quarkus/it/resteasy/reactive/kotlin/GreetingResource.kt b/integration-tests/resteasy-reactive-kotlin/standard/src/main/kotlin/io/quarkus/it/resteasy/reactive/kotlin/GreetingResource.kt index 5adad745db57c7..c5fd5403b6aabf 100644 --- a/integration-tests/resteasy-reactive-kotlin/standard/src/main/kotlin/io/quarkus/it/resteasy/reactive/kotlin/GreetingResource.kt +++ b/integration-tests/resteasy-reactive-kotlin/standard/src/main/kotlin/io/quarkus/it/resteasy/reactive/kotlin/GreetingResource.kt @@ -8,11 +8,16 @@ import jakarta.ws.rs.core.Context import jakarta.ws.rs.core.HttpHeaders import jakarta.ws.rs.core.Response import jakarta.ws.rs.core.UriInfo +import java.util.concurrent.atomic.AtomicReference import org.jboss.resteasy.reactive.RestHeader @Path("/greeting") class GreetingResource(val headers: HttpHeaders) { + companion object { + val MY_PROPERTY = AtomicReference("unset") + } + @GET suspend fun testSuspend(@RestHeader("firstName") firstName: String): Greeting { val lastName = headers.getHeaderString("lastName") @@ -28,6 +33,12 @@ class GreetingResource(val headers: HttpHeaders) { greeting: Greeting, @Context uriInfo: UriInfo ) = Response.ok(greeting).build() + + @GET + @Path("prop") + fun testProp(): String? { + return MY_PROPERTY.get() + } } data class Greeting(val message: String) diff --git a/integration-tests/resteasy-reactive-kotlin/standard/src/main/kotlin/io/quarkus/it/resteasy/reactive/kotlin/RegisterCustomModuleCustomizer.kt b/integration-tests/resteasy-reactive-kotlin/standard/src/main/kotlin/io/quarkus/it/resteasy/reactive/kotlin/RegisterCustomModuleCustomizer.kt new file mode 100644 index 00000000000000..1600498fb6ad6e --- /dev/null +++ b/integration-tests/resteasy-reactive-kotlin/standard/src/main/kotlin/io/quarkus/it/resteasy/reactive/kotlin/RegisterCustomModuleCustomizer.kt @@ -0,0 +1,15 @@ +package io.quarkus.it.resteasy.reactive.kotlin + +import com.fasterxml.jackson.databind.ObjectMapper +import io.quarkus.jackson.ObjectMapperCustomizer +import jakarta.inject.Singleton +import org.eclipse.microprofile.config.inject.ConfigProperty + +@Singleton +class RegisterCustomModuleCustomizer : ObjectMapperCustomizer { + @ConfigProperty(name = "test.prop") lateinit var testProp: String + + override fun customize(objectMapper: ObjectMapper) { + GreetingResource.MY_PROPERTY.set(testProp) + } +} diff --git a/integration-tests/resteasy-reactive-kotlin/standard/src/main/resources/application.properties b/integration-tests/resteasy-reactive-kotlin/standard/src/main/resources/application.properties index dbd2604ffa9a1c..5e5d8b8138f0ca 100644 --- a/integration-tests/resteasy-reactive-kotlin/standard/src/main/resources/application.properties +++ b/integration-tests/resteasy-reactive-kotlin/standard/src/main/resources/application.properties @@ -29,3 +29,5 @@ mp.messaging.incoming.countries-t2-in.auto.offset.reset=earliest mp.messaging.incoming.countries-t2-in.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer quarkus.package.quiltflower.enabled=true + +test.prop=test diff --git a/integration-tests/resteasy-reactive-kotlin/standard/src/test/kotlin/io/quarkus/it/resteasy/reactive/kotlin/GreetingResourceTest.kt b/integration-tests/resteasy-reactive-kotlin/standard/src/test/kotlin/io/quarkus/it/resteasy/reactive/kotlin/GreetingResourceTest.kt index 226058ffe4da68..2541a7a53f9083 100644 --- a/integration-tests/resteasy-reactive-kotlin/standard/src/test/kotlin/io/quarkus/it/resteasy/reactive/kotlin/GreetingResourceTest.kt +++ b/integration-tests/resteasy-reactive-kotlin/standard/src/test/kotlin/io/quarkus/it/resteasy/reactive/kotlin/GreetingResourceTest.kt @@ -39,4 +39,13 @@ class GreetingResourceTest { fun testNoopCoroutine() { When { get("/greeting/noop") } Then { statusCode(204) } } + + @Test + fun testProp() { + When { get("/greeting/prop") } Then + { + statusCode(200) + body(CoreMatchers.`is`("prod")) + } + } }