From 34b12d96a0f409f6a1d3954f65e4e985c408b880 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 9 Apr 2024 16:08:59 +0200 Subject: [PATCH 01/29] Add .mvn/.develocity/ to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index cf125852ce54b..2cb8e2e551695 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,5 @@ nb-configuration.xml .envrc .jekyll-cache .mvn/.gradle-enterprise +.mvn/.develocity .quarkus From c40968fd3e0a02b90f192d7bb9a4bc98ab7ebbc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 22:46:00 +0000 Subject: [PATCH 02/29] Bump com.fasterxml.jackson:jackson-bom from 2.16.1 to 2.17.0 Bumps [com.fasterxml.jackson:jackson-bom](https://github.com/FasterXML/jackson-bom) from 2.16.1 to 2.17.0. - [Commits](https://github.com/FasterXML/jackson-bom/compare/jackson-bom-2.16.1...jackson-bom-2.17.0) --- updated-dependencies: - dependency-name: com.fasterxml.jackson:jackson-bom dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] (cherry picked from commit 92b491208541e2db51056baf3021aae7f056cd1a) --- bom/application/pom.xml | 2 +- independent-projects/extension-maven-plugin/pom.xml | 2 +- independent-projects/resteasy-reactive/pom.xml | 2 +- independent-projects/tools/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index fc8c1151de642..4ec9caada74c4 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -92,7 +92,7 @@ 23.1.2 1.8.0 - 2.16.1 + 2.17.0 1.0.0.Final 3.14.0 1.16.1 diff --git a/independent-projects/extension-maven-plugin/pom.xml b/independent-projects/extension-maven-plugin/pom.xml index 512b1e0453f97..421090a13c0fa 100644 --- a/independent-projects/extension-maven-plugin/pom.xml +++ b/independent-projects/extension-maven-plugin/pom.xml @@ -41,7 +41,7 @@ 3.12.1 3.2.1 3.2.5 - 2.16.1 + 2.17.0 1.4.0 5.10.2 diff --git a/independent-projects/resteasy-reactive/pom.xml b/independent-projects/resteasy-reactive/pom.xml index 1bd5c8e1dd860..e9186770ab69f 100644 --- a/independent-projects/resteasy-reactive/pom.xml +++ b/independent-projects/resteasy-reactive/pom.xml @@ -64,7 +64,7 @@ 4.5.7 5.4.0 1.0.0.Final - 2.16.1 + 2.17.0 2.6.0 3.0.2 3.0.3 diff --git a/independent-projects/tools/pom.xml b/independent-projects/tools/pom.xml index f96f2eeda0bfc..9c17353f85dd9 100644 --- a/independent-projects/tools/pom.xml +++ b/independent-projects/tools/pom.xml @@ -49,7 +49,7 @@ 3.25.3 - 2.16.1 + 2.17.0 4.0.1 5.10.2 1.26.1 From 257c5a93cd32290e508b28a92d397785c744cb47 Mon Sep 17 00:00:00 2001 From: Francesco Nigro Date: Wed, 27 Mar 2024 12:30:24 +0100 Subject: [PATCH 03/29] Jackson should use HybridJacksonPool (cherry picked from commit 982fdb856c845d4bfbe88d630857dda6de17305a) --- .../jackson/deployment/JacksonDefaultPoolTest.java | 14 ++++++++++++++ .../VertxHybridPoolObjectMapperCustomizer.java | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 extensions/jackson/deployment/src/test/java/io/quarkus/jackson/deployment/JacksonDefaultPoolTest.java diff --git a/extensions/jackson/deployment/src/test/java/io/quarkus/jackson/deployment/JacksonDefaultPoolTest.java b/extensions/jackson/deployment/src/test/java/io/quarkus/jackson/deployment/JacksonDefaultPoolTest.java new file mode 100644 index 0000000000000..715f9d62ff3ba --- /dev/null +++ b/extensions/jackson/deployment/src/test/java/io/quarkus/jackson/deployment/JacksonDefaultPoolTest.java @@ -0,0 +1,14 @@ +package io.quarkus.jackson.deployment; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.util.JsonRecyclerPools; + +public class JacksonDefaultPoolTest { + + @Test + public void validateDefaultJacksonPool() { + Assertions.assertThat(JsonRecyclerPools.defaultPool()).isInstanceOf(JsonRecyclerPools.LockFreePool.class); + } +} diff --git a/extensions/jackson/runtime/src/main/java/io/quarkus/jackson/runtime/VertxHybridPoolObjectMapperCustomizer.java b/extensions/jackson/runtime/src/main/java/io/quarkus/jackson/runtime/VertxHybridPoolObjectMapperCustomizer.java index 6f7bbe0cd3851..3254837f6e54d 100644 --- a/extensions/jackson/runtime/src/main/java/io/quarkus/jackson/runtime/VertxHybridPoolObjectMapperCustomizer.java +++ b/extensions/jackson/runtime/src/main/java/io/quarkus/jackson/runtime/VertxHybridPoolObjectMapperCustomizer.java @@ -10,7 +10,9 @@ public class VertxHybridPoolObjectMapperCustomizer implements ObjectMapperCustom @Override public void customize(ObjectMapper objectMapper) { - if (objectMapper.getFactory()._getRecyclerPool() == JsonRecyclerPools.defaultPool()) { + var existingMapperPool = objectMapper.getFactory()._getRecyclerPool(); + // JsonRecyclerPools.defaultPool() by default should create a LockFreePool + if (existingMapperPool instanceof JsonRecyclerPools.LockFreePool) { objectMapper.getFactory().setRecyclerPool(HybridJacksonPool.getInstance()); } } From d2673c825ade4aac385586ceb337d56f0a084e46 Mon Sep 17 00:00:00 2001 From: Julien Ponge Date: Tue, 9 Apr 2024 17:00:31 +0200 Subject: [PATCH 04/29] Fix native compilation for Netty and Mutiny See #39819 and #39788 (cherry picked from commit b35ae008f0e84585f37b80dd1861b208ed6fd79a) --- .../main/java/io/quarkus/netty/deployment/NettyProcessor.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java b/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java index a7d5ae3e2c2a5..4c2741d2092ed 100644 --- a/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java +++ b/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java @@ -105,6 +105,8 @@ NativeImageConfigBuildItem build( .addRuntimeInitializedClass("io.netty.handler.ssl.ReferenceCountedOpenSslEngine") .addRuntimeInitializedClass("io.netty.handler.ssl.ReferenceCountedOpenSslContext") .addRuntimeInitializedClass("io.netty.handler.ssl.ReferenceCountedOpenSslClientContext") + .addRuntimeInitializedClass("io.netty.handler.ssl.JdkSslServerContext") + .addRuntimeInitializedClass("io.netty.handler.ssl.JdkSslClientContext") .addRuntimeInitializedClass("io.netty.handler.ssl.util.ThreadLocalInsecureRandom") .addRuntimeInitializedClass("io.netty.buffer.ByteBufUtil$HexUtil") .addRuntimeInitializedClass("io.netty.buffer.PooledByteBufAllocator") From 8cb1a3e39222e36855fea1d7f8934b377626653c Mon Sep 17 00:00:00 2001 From: Eric Deandrea Date: Tue, 2 Apr 2024 12:23:32 -0400 Subject: [PATCH 05/29] Removing `quarkus-panache-common` annotation processor from docs (cherry picked from commit c5890c7f506b78cfefaabeacd67331c1db827110) --- .../main/asciidoc/hibernate-orm-panache.adoc | 31 ------------------- .../asciidoc/hibernate-reactive-panache.adoc | 31 ------------------- 2 files changed, 62 deletions(-) diff --git a/docs/src/main/asciidoc/hibernate-orm-panache.adoc b/docs/src/main/asciidoc/hibernate-orm-panache.adoc index 3e15bd753e261..12d76c52dd4f2 100644 --- a/docs/src/main/asciidoc/hibernate-orm-panache.adoc +++ b/docs/src/main/asciidoc/hibernate-orm-panache.adoc @@ -75,37 +75,6 @@ Clone the Git repository: `git clone {quickstarts-clone-url}`, or download an {q The solution is located in the `hibernate-orm-panache-quickstart` link:{quickstarts-tree-url}/hibernate-orm-panache-quickstart[directory]. -[NOTE] -==== -If your project is already configured to use other annotation processors, you will need to additionally add the Panache annotation processor: - -[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] -.pom.xml ----- - - maven-compiler-plugin - ${compiler-plugin.version} - - ${maven.compiler.parameters} - - - - io.quarkus - quarkus-panache-common - ${quarkus.platform.version} - - - - ----- - -[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] -.build.gradle ----- -annotationProcessor("io.quarkus:quarkus-panache-common") ----- -==== - == Setting up and configuring Hibernate ORM with Panache To get started: diff --git a/docs/src/main/asciidoc/hibernate-reactive-panache.adoc b/docs/src/main/asciidoc/hibernate-reactive-panache.adoc index 846a09c177b9b..8b6d16a9ad2f4 100644 --- a/docs/src/main/asciidoc/hibernate-reactive-panache.adoc +++ b/docs/src/main/asciidoc/hibernate-reactive-panache.adoc @@ -71,37 +71,6 @@ Clone the Git repository: `git clone {quickstarts-clone-url}`, or download an {q The solution is located in the `hibernate-reactive-panache-quickstart` link:{quickstarts-tree-url}/hibernate-reactive-panache-quickstart[directory]. -[NOTE] -==== -If your project is already configured to use other annotation processors, you will need to additionally add the Panache annotation processor: - -[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] -.pom.xml ----- - - maven-compiler-plugin - ${compiler-plugin.version} - - ${maven.compiler.parameters} - - - - io.quarkus - quarkus-panache-common - ${quarkus.platform.version} - - - - ----- - -[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] -.build.gradle ----- -annotationProcessor("io.quarkus:quarkus-panache-common") ----- -==== - == Setting up and configuring Hibernate Reactive with Panache To get started: From 1cabffe0a92fac2941b7aa31cb1a0d6cd7d79cc9 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 2 Apr 2024 16:28:05 +0200 Subject: [PATCH 06/29] Add js-scriptengine and collections as parent first artifacts Related to #39833 (cherry picked from commit cb0eb3836b6d2b4474fecd57ad1e837f4d561129) --- core/runtime/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/runtime/pom.xml b/core/runtime/pom.xml index 00eac75074262..42fe22a7690e7 100644 --- a/core/runtime/pom.xml +++ b/core/runtime/pom.xml @@ -160,6 +160,7 @@ org.graalvm.polyglot:js-community org.graalvm.js:js-language + org.graalvm.js:js-scriptengine org.graalvm.polyglot:js org.graalvm.polyglot:polyglot org.graalvm.regex:regex @@ -170,6 +171,7 @@ org.graalvm.shadowed:icu4j org.graalvm.sdk:jniutils org.graalvm.sdk:word + org.graalvm.sdk:collections org.graalvm.sdk:native-bridge io.quarkus:quarkus-bootstrap-core @@ -220,6 +222,7 @@ org.graalvm.polyglot:js-community org.graalvm.js:js-language + org.graalvm.js:js-scriptengine org.graalvm.polyglot:js org.graalvm.polyglot:polyglot org.graalvm.regex:regex @@ -230,6 +233,7 @@ org.graalvm.shadowed:icu4j org.graalvm.sdk:jniutils org.graalvm.sdk:word + org.graalvm.sdk:collections org.graalvm.sdk:native-bridge io.quarkus:quarkus-bootstrap-runner From 24a864ebb023c7a723365eb0ae93e120658c6a04 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Sun, 31 Mar 2024 23:20:27 +0100 Subject: [PATCH 07/29] Explain in the docs how to map the X509 CN attribute to roles (cherry picked from commit a7d296b7a7f28f18160ce5c55bcb45dd2cd3796a) --- .../security-authentication-mechanisms.adoc | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc index 9584b86abb792..caf601b1cec70 100644 --- a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc +++ b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc @@ -269,10 +269,41 @@ CertificateCredential credential = identity.getCredential(CertificateCredential. X509Certificate certificate = credential.getCertificate(); ---- -==== Authorization +[[map-certificate-attributes-to-roles]] +==== Mapping certificate attributes to roles + +The information from the client certificate can be used to add roles to Quarkus `SecurityIdentity`. + +You can add new roles to `SecurityIdentity` after checking a client certificate's common name (CN) attribute. +The easiest way to add new roles is to use a certificate attribute to role mapping feature. + +For example, you can update the properties shown in the section which introduces <> as follows: + +[source,properties] +---- +quarkus.http.ssl.certificate.key-store-file=server-keystore.jks +quarkus.http.ssl.certificate.key-store-password=the_key_store_secret +quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks +quarkus.http.ssl.certificate.trust-store-password=the_trust_store_secret +quarkus.http.ssl.client-auth=required +quarkus.http.insecure-requests=disabled + +quarkus.http.auth.certificate-role-properties=cert-role-mappings.properties <1> + +quarkus.http.auth.permission.certauthenticated.paths=/* <2> +quarkus.http.auth.permission.certauthenticated.policy=role-policy-cert <2> +quarkus.http.auth.policy.role-policy-cert.roles-allowed=user,admin <2> +---- +<1> The `cert-role-mappings.properties` classpath resource contains a map of certificate's CN values to roles in the form `CN=role` or `CN=role1,role2`, etc. Let's assume it contains three entries: `alice=user,admin`, `bob=user` and `jdoe=tester`. +<2> Use HTTP security policy to require that `SecurityIdentity` must have either `user` or `admin` roles for the requests to be authorized. + +Given the preceeding configuration, the request is authorized if the client certificate's CN attribute is equal to `alice` or `bob` and forbidden if it is equal to `jdoe`. + +==== Using certificate attributes to augment SecurityIdentity + +You can always register `SecurityIdentityAugmentor` if the automatic <> option does not suit. +Custom `SecurityIdentityAugmentor` can check the values of different client certificate attributes and augment the `SecurityIdentity` accordingly. -The information from the client certificate can be used to enhance Quarkus `SecurityIdentity`. -For example, you can add new roles after checking a client certificate subject name, and so on. For more information about customizing `SecurityIdentity`, see the xref:security-customization.adoc#security-identity-customization[Security identity customization] section in the Quarkus "Security tips and tricks" guide. [[other-supported-authentication-mechanisms]] From 9dd3e2f0d4043e3832dda2f5347aaff324ab5d4b Mon Sep 17 00:00:00 2001 From: Marek Skacelik Date: Wed, 3 Apr 2024 12:43:18 +0200 Subject: [PATCH 08/29] Added MP's Input.class to the index (SmallRye GraphQL Client) + test (cherry picked from commit 067643be43888e4ec9c8e35209998a0ba63d76ec) --- .../SmallRyeGraphQLClientProcessor.java | 2 ++ ...ParameterInputNameWithClientModelTest.java | 34 +++++++++++++++++++ .../client/deployment/model/PersonDto.java | 23 +++++++++++++ .../deployment/model/TestingGraphQLApi.java | 14 ++++++++ .../model/TestingGraphQLClientApi.java | 3 ++ 5 files changed, 76 insertions(+) create mode 100644 extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypeSafeGraphQLParameterInputNameWithClientModelTest.java create mode 100644 extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/PersonDto.java diff --git a/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java b/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java index 7bfd1f68aea4c..f61dcbbf2d5d9 100644 --- a/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java +++ b/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java @@ -12,6 +12,7 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Singleton; +import org.eclipse.microprofile.graphql.Input; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; @@ -236,6 +237,7 @@ void setAdditionalClassesToIndex(BuildProducer jar + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); + + @Inject + TestingGraphQLClientApi client; + + @Test + public void performQuery() { + final String expectedName = "Mark"; + String actualPerson = client.getNameOfThePerson(new PersonDto(expectedName)); + assertEquals(expectedName, actualPerson); + } +} diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/PersonDto.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/PersonDto.java new file mode 100644 index 0000000000000..c0b6129225c29 --- /dev/null +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/PersonDto.java @@ -0,0 +1,23 @@ +package io.quarkus.smallrye.graphql.client.deployment.model; + +import org.eclipse.microprofile.graphql.Input; + +@Input("PersonInput") +public class PersonDto { + private String name; + + public PersonDto() { + } + + public PersonDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLApi.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLApi.java index f6f73aed7485e..df3b331195ded 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLApi.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLApi.java @@ -8,6 +8,7 @@ import org.eclipse.microprofile.graphql.Query; import io.quarkus.vertx.http.runtime.CurrentVertxRequest; +import io.smallrye.graphql.execution.context.SmallRyeContext; @GraphQLApi public class TestingGraphQLApi { @@ -15,6 +16,9 @@ public class TestingGraphQLApi { @Inject CurrentVertxRequest request; + @Inject + SmallRyeContext ctx; + @Query public List people() { Person person1 = new Person(); @@ -36,4 +40,14 @@ public String returnHeader(String key) { return request.getCurrent().request().getHeader(key); } + private final String EXPECTED_QUERY_FOR_NAME_OF_THE_PERSON = "query nameOfThePerson($personDto: PersonInput) { nameOfThePerson(personDto: $personDto) }"; + + @Query + public String getNameOfThePerson(PersonDto personDto) { + if (!ctx.getQuery().equals(EXPECTED_QUERY_FOR_NAME_OF_THE_PERSON)) + throw new RuntimeException( + String.format("Wrong Query - expected: %s\n actual: %s", EXPECTED_QUERY_FOR_NAME_OF_THE_PERSON, + ctx.getQuery())); + return personDto.getName(); + } } diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLClientApi.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLClientApi.java index f28ccc571feb6..e456c86bd6396 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLClientApi.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLClientApi.java @@ -15,4 +15,7 @@ public interface TestingGraphQLClientApi { @Query public String returnHeader(String key); + @Query + public String getNameOfThePerson(PersonDto personDto); + } From a64a63575a0c605ae9e4b1afc2bc8b16f078fd42 Mon Sep 17 00:00:00 2001 From: Jan Martiska Date: Wed, 3 Apr 2024 16:46:23 +0200 Subject: [PATCH 09/29] Fix broken GraphQL client tests (cherry picked from commit bf31a24edafedb3cb54e255866feea20c1c6996e) --- .../deployment/DynamicGraphQLClientInjectionTest.java | 3 ++- ...DynamicGraphQLClientInjectionWithQuarkusConfigTest.java | 3 ++- .../DynamicGraphQLClientProgrammaticUsageTest.java | 3 ++- .../client/deployment/StorkAndGraphQLClientTest.java | 3 ++- .../client/deployment/TypesafeGraphQLClientFQNameTest.java | 4 +++- .../deployment/TypesafeGraphQLClientInjectionTest.java | 3 ++- ...ypesafeGraphQLClientInjectionWithQuarkusConfigTest.java | 3 ++- .../TypesafeGraphQLClientProgrammaticUsageTest.java | 3 ++- ...eGraphQLClientProgrammaticUsageWithClientModelTest.java | 7 +++++-- .../deployment/TypesafeGraphQLClientShortcutTest.java | 4 +++- 10 files changed, 25 insertions(+), 11 deletions(-) diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionTest.java index c1553ba681ede..33fc27e86e43a 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionTest.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.test.QuarkusUnitTest; import io.smallrye.graphql.client.GraphQLClient; @@ -32,7 +33,7 @@ public class DynamicGraphQLClientInjectionTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset("people-client/mp-graphql/url=" + url + "\n" + "people-client/mp-graphql/header/My-Header=My-Value"), "application.properties") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionWithQuarkusConfigTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionWithQuarkusConfigTest.java index 2bbc1133d4083..abf35039193ec 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionWithQuarkusConfigTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionWithQuarkusConfigTest.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.test.QuarkusUnitTest; import io.smallrye.graphql.client.GraphQLClient; @@ -32,7 +33,7 @@ public class DynamicGraphQLClientInjectionWithQuarkusConfigTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset("quarkus.smallrye-graphql-client.people.url=" + url + "\n" + "quarkus.smallrye-graphql-client.people.header.My-Header=My-Value"), "application.properties") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientProgrammaticUsageTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientProgrammaticUsageTest.java index 908efe65ca79b..c6b9590ccd3cb 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientProgrammaticUsageTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientProgrammaticUsageTest.java @@ -13,6 +13,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.http.TestHTTPResource; @@ -26,7 +27,7 @@ public class DynamicGraphQLClientProgrammaticUsageTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, Person.class, PersonDto.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); @TestHTTPResource diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/StorkAndGraphQLClientTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/StorkAndGraphQLClientTest.java index bde9d888ddaec..344599fa07e29 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/StorkAndGraphQLClientTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/StorkAndGraphQLClientTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -21,7 +22,7 @@ public class StorkAndGraphQLClientTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset( "quarkus.smallrye-graphql-client.typesafeclient.url=stork://foo-service/graphql\n" + "quarkus.stork.foo-service.service-discovery.type=static\n" + diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientFQNameTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientFQNameTest.java index d3b1033ce74e4..88c881bbc2ee4 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientFQNameTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientFQNameTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApiWithNoConfigKey; import io.quarkus.test.QuarkusUnitTest; @@ -27,7 +28,8 @@ public class TypesafeGraphQLClientFQNameTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApiWithNoConfigKey.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApiWithNoConfigKey.class, Person.class, + PersonDto.class) .addAsResource( new StringAsset( "quarkus.smallrye-graphql-client.\"io.quarkus.smallrye.graphql." + diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java index c75b3fb652109..07c8e796380d0 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -24,7 +25,7 @@ public class TypesafeGraphQLClientInjectionTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset("typesafeclient/mp-graphql/url=" + url + "\n" + "typesafeclient/mp-graphql/header/My-Header=My-Value"), "application.properties") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java index 1b066b01ab7ac..03d7197993851 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -24,7 +25,7 @@ public class TypesafeGraphQLClientInjectionWithQuarkusConfigTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset("quarkus.smallrye-graphql-client.typesafeclient.url=" + url + "\n" + "quarkus.smallrye-graphql-client.typesafeclient.header.My-Header=My-Value"), "application.properties") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageTest.java index c06279e6eb031..b3fc7caa0bb13 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -21,7 +22,7 @@ public class TypesafeGraphQLClientProgrammaticUsageTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); @TestHTTPResource diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageWithClientModelTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageWithClientModelTest.java index ec091a6a82cad..768e5dafe143c 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageWithClientModelTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageWithClientModelTest.java @@ -6,12 +6,14 @@ import java.net.URL; import java.util.List; +import org.eclipse.microprofile.graphql.Input; import org.jboss.jandex.Index; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -26,7 +28,7 @@ public class TypesafeGraphQLClientProgrammaticUsageWithClientModelTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); @TestHTTPResource @@ -34,7 +36,8 @@ public class TypesafeGraphQLClientProgrammaticUsageWithClientModelTest { @Test public void performQuery() throws IOException { - Index index = Index.of(GraphQLClientApi.class, TestingGraphQLClientApi.class, Person.class); + Index index = Index.of(GraphQLClientApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class, + Input.class); TestingGraphQLClientApi client = ((VertxTypesafeGraphQLClientBuilder) TypesafeGraphQLClientBuilder.newBuilder()) .clientModels(ClientModelBuilder.build(index)) .endpoint(url.toString() + "/graphql") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientShortcutTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientShortcutTest.java index 84840596fe0a9..8e66221907ec9 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientShortcutTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientShortcutTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApiWithNoConfigKey; import io.quarkus.test.QuarkusUnitTest; @@ -28,7 +29,8 @@ public class TypesafeGraphQLClientShortcutTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApiWithNoConfigKey.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApiWithNoConfigKey.class, Person.class, + PersonDto.class) .addAsResource( new StringAsset( "quarkus.smallrye-graphql-client.TestingGraphQLClientApiWithNoConfigKey.url=" + url), From 1b295392c587c51293f236ded47f835a604dc00d Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Wed, 3 Apr 2024 17:55:07 +0300 Subject: [PATCH 10/29] Warn users when using older GraalVM or Mandrel versions Although we try to keep backwards compatibility with older GraalVM or Mandrel versions, these versions should not be considered as fully supported by the users, as the compatibility might break at any time (even at a minor level patch). (cherry picked from commit c84ac1d7672cb1ca0996676e784f5545dd4d62c0) --- .../quarkus/deployment/pkg/steps/GraalVM.java | 17 +++++++++++++++++ .../pkg/steps/NativeImageBuildStep.java | 10 ++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java index b581c38415e98..deda3c9d1f965 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java @@ -186,8 +186,21 @@ public static final class Version implements Comparable { public static final Version VERSION_23_1_0 = new Version("GraalVM 23.1.0", "23.1.0", "21", Distribution.GRAALVM); public static final Version VERSION_24_0_0 = new Version("GraalVM 24.0.0", "24.0.0", "22", Distribution.GRAALVM); + /** + * The minimum version of GraalVM supported by Quarkus. + * Versions prior to this are expected to cause major issues. + */ public static final Version MINIMUM = VERSION_22_2_0; + /** + * The current version of GraalVM supported by Quarkus. + * This version is the one actively being tested and is expected to give the best experience. + */ public static final Version CURRENT = VERSION_23_1_0; + /** + * The minimum version of GraalVM officially supported by Quarkus. + * Versions prior to this are expected to work but are not given the same level of testing or priority. + */ + public static final Version MINIMUM_SUPPORTED = CURRENT; final String fullVersion; public final Runtime.Version javaVersion; @@ -227,6 +240,10 @@ boolean isObsolete() { return this.compareTo(MINIMUM) < 0; } + boolean isSupported() { + return this.compareTo(MINIMUM_SUPPORTED) >= 0; + } + boolean isMandrel() { return distribution == Distribution.MANDREL; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java index ccdd7ae667682..ea1ed71b4534f 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java @@ -473,9 +473,15 @@ private void checkGraalVMVersion(GraalVM.Version version) { log.info("Running Quarkus native-image plugin on " + version.distribution.name() + " " + version.getVersionAsString() + " JDK " + version.javaVersion); if (version.isObsolete()) { - throw new IllegalStateException("Out of date version of GraalVM detected: " + version.getVersionAsString() + "." + throw new IllegalStateException( + "Out of date version of GraalVM or Mandrel detected: " + version.getVersionAsString() + "." + + " Quarkus currently supports " + GraalVM.Version.CURRENT.getVersionAsString() + + ". Please upgrade to this version."); + } + if (!version.isSupported()) { + log.warn("You are using an older version of GraalVM or Mandrel : " + version.getVersionAsString() + "." + " Quarkus currently supports " + GraalVM.Version.CURRENT.getVersionAsString() - + ". Please upgrade GraalVM to this version."); + + ". Please upgrade to this version."); } } From a6574d4ee4ecfd1c517969ffaa99a4682b80237d Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 2 Apr 2024 15:34:42 +0300 Subject: [PATCH 11/29] No build time init of classes used in `UnsafeAccessedFieldBuildItem` Use the Feature classloader instead of the default one to prevent classes being loaded to register fields as unsafe accessed to end up being build time initialized. Similarly ensure that the registration is done after class initialization configuration to prevent classes from being configured for runtime initialization because of the unsafe access registration. (cherry picked from commit 07f706365f09dd582eb865212357869516cca575) --- .../steps/NativeImageFeatureStep.java | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java index 7fff7025f304e..28e1c088653e6 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java @@ -78,28 +78,6 @@ public void write(String s, byte[] bytes) { MethodCreator beforeAn = file.getMethodCreator("beforeAnalysis", "V", BEFORE_ANALYSIS_ACCESS); TryBlock overallCatch = beforeAn.tryBlock(); - ResultHandle beforeAnalysisParam = beforeAn.getMethodParam(0); - - MethodCreator registerAsUnsafeAccessed = file - .getMethodCreator("registerAsUnsafeAccessed", void.class, Feature.BeforeAnalysisAccess.class) - .setModifiers(Modifier.PRIVATE | Modifier.STATIC); - for (UnsafeAccessedFieldBuildItem unsafeAccessedField : unsafeAccessedFields) { - TryBlock tc = registerAsUnsafeAccessed.tryBlock(); - ResultHandle declaringClassHandle = tc.invokeStaticMethod( - ofMethod(Class.class, "forName", Class.class, String.class), - tc.load(unsafeAccessedField.getDeclaringClass())); - ResultHandle fieldHandle = tc.invokeVirtualMethod( - ofMethod(Class.class, "getDeclaredField", Field.class, String.class), declaringClassHandle, - tc.load(unsafeAccessedField.getFieldName())); - tc.invokeInterfaceMethod( - ofMethod(Feature.BeforeAnalysisAccess.class, "registerAsUnsafeAccessed", void.class, Field.class), - registerAsUnsafeAccessed.getMethodParam(0), fieldHandle); - CatchBlockCreator cc = tc.addCatch(Throwable.class); - cc.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), cc.getCaughtException()); - } - registerAsUnsafeAccessed.returnVoid(); - overallCatch.invokeStaticMethod(registerAsUnsafeAccessed.getMethodDescriptor(), beforeAnalysisParam); - overallCatch.invokeStaticMethod(BUILD_TIME_INITIALIZATION, overallCatch.marshalAsArray(String.class, overallCatch.load(""))); // empty string means initialize everything @@ -179,6 +157,35 @@ public void write(String s, byte[] bytes) { overallCatch.invokeStaticMethod(runtimeReinitializedClasses.getMethodDescriptor()); } + // Ensure registration of fields being accessed through unsafe is done last to ensure that the class + // initialization configuration is done first. Registering the fields before configuring class initialization + // may results in classes being marked for runtime initialization even if not explicitly requested. + if (!unsafeAccessedFields.isEmpty()) { + ResultHandle beforeAnalysisParam = beforeAn.getMethodParam(0); + MethodCreator registerAsUnsafeAccessed = file + .getMethodCreator("registerAsUnsafeAccessed", void.class, Feature.BeforeAnalysisAccess.class) + .setModifiers(Modifier.PRIVATE | Modifier.STATIC); + ResultHandle thisClass = registerAsUnsafeAccessed.loadClassFromTCCL(GRAAL_FEATURE); + ResultHandle cl = registerAsUnsafeAccessed + .invokeVirtualMethod(ofMethod(Class.class, "getClassLoader", ClassLoader.class), thisClass); + for (UnsafeAccessedFieldBuildItem unsafeAccessedField : unsafeAccessedFields) { + TryBlock tc = registerAsUnsafeAccessed.tryBlock(); + ResultHandle declaringClassHandle = tc.invokeStaticMethod( + ofMethod(Class.class, "forName", Class.class, String.class, boolean.class, ClassLoader.class), + tc.load(unsafeAccessedField.getDeclaringClass()), tc.load(false), cl); + ResultHandle fieldHandle = tc.invokeVirtualMethod( + ofMethod(Class.class, "getDeclaredField", Field.class, String.class), declaringClassHandle, + tc.load(unsafeAccessedField.getFieldName())); + tc.invokeInterfaceMethod( + ofMethod(Feature.BeforeAnalysisAccess.class, "registerAsUnsafeAccessed", void.class, Field.class), + registerAsUnsafeAccessed.getMethodParam(0), fieldHandle); + CatchBlockCreator cc = tc.addCatch(Throwable.class); + cc.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), cc.getCaughtException()); + } + registerAsUnsafeAccessed.returnVoid(); + overallCatch.invokeStaticMethod(registerAsUnsafeAccessed.getMethodDescriptor(), beforeAnalysisParam); + } + CatchBlockCreator print = overallCatch.addCatch(Throwable.class); print.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), print.getCaughtException()); From c15f39c6c85acdfcd2a13168c570cdcc9620d51e Mon Sep 17 00:00:00 2001 From: Damiano Renfer Date: Wed, 27 Mar 2024 10:46:16 +0100 Subject: [PATCH 12/29] Fix StorkClientRequestFilter exception handling Exceptions were not caught properly because a Uni subscription was done outside a try-catch block. (cherry picked from commit 04cffc5df44d7d97557b55869fd61d4f450fe2d9) --- .../client/impl/StorkClientRequestFilter.java | 105 +++++++++--------- 1 file changed, 50 insertions(+), 55 deletions(-) diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/StorkClientRequestFilter.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/StorkClientRequestFilter.java index 60990009a9d88..92ec1af83341f 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/StorkClientRequestFilter.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/StorkClientRequestFilter.java @@ -15,9 +15,7 @@ import org.jboss.resteasy.reactive.client.spi.ResteasyReactiveClientRequestFilter; import io.smallrye.mutiny.Multi; -import io.smallrye.mutiny.Uni; import io.smallrye.stork.Stork; -import io.smallrye.stork.api.ServiceInstance; @Priority(Priorities.AUTHENTICATION) @Provider @@ -34,67 +32,64 @@ public void filter(ResteasyReactiveClientRequestContext requestContext) { } requestContext.suspend(); - Uni serviceInstance; boolean measureTime = shouldMeasureTime(requestContext.getResponseType()); try { - serviceInstance = Stork.getInstance() + Stork.getInstance() .getService(serviceName) - .selectInstanceAndRecordStart(measureTime); - } catch (Throwable e) { - log.error("Error selecting service instance for serviceName: " + serviceName, e); - requestContext.resume(e); - return; - } - - serviceInstance.subscribe() - .with(instance -> { - boolean isHttps = instance.isSecure() || "storks".equals(uri.getScheme()); - String scheme = isHttps ? "https" : "http"; - try { - // In the case the service instance does not set the host and/or port - String host = instance.getHost() == null ? "localhost" : instance.getHost(); - int port = instance.getPort(); - if (instance.getPort() == 0) { - if (isHttps) { - port = 433; - } else { - port = 80; - } - } - // Service instance can also contain an optional path. - Optional path = instance.getPath(); - String actualPath = uri.getRawPath(); - if (path.isPresent()) { - var p = path.get(); - if (!p.startsWith("/")) { - p = "/" + p; + .selectInstanceAndRecordStart(measureTime) + .subscribe() + .with(instance -> { + boolean isHttps = instance.isSecure() || "storks".equals(uri.getScheme()); + String scheme = isHttps ? "https" : "http"; + try { + // In the case the service instance does not set the host and/or port + String host = instance.getHost() == null ? "localhost" : instance.getHost(); + int port = instance.getPort(); + if (instance.getPort() == 0) { + if (isHttps) { + port = 433; + } else { + port = 80; + } } - if (actualPath == null) { - actualPath = p; - } else { - // Append both. - if (actualPath.startsWith("/") || p.endsWith("/")) { - actualPath = p + actualPath; + // Service instance can also contain an optional path. + Optional path = instance.getPath(); + String actualPath = uri.getRawPath(); + if (path.isPresent()) { + var p = path.get(); + if (!p.startsWith("/")) { + p = "/" + p; + } + if (actualPath == null) { + actualPath = p; } else { - actualPath = p + "/" + actualPath; + // Append both. + if (actualPath.startsWith("/") || p.endsWith("/")) { + actualPath = p + actualPath; + } else { + actualPath = p + "/" + actualPath; + } } } + //To avoid the path double encoding we create uri with path=null and set the path after + URI newUri = new URI(scheme, + uri.getUserInfo(), host, port, + null, uri.getQuery(), uri.getFragment()); + URI build = UriBuilder.fromUri(newUri).path(actualPath).build(); + requestContext.setUri(build); + if (measureTime && instance.gatherStatistics()) { + requestContext.setCallStatsCollector(instance); + } + requestContext.resume(); + } catch (URISyntaxException e) { + requestContext.resume(new IllegalArgumentException("Invalid URI", e)); } - //To avoid the path double encoding we create uri with path=null and set the path after - URI newUri = new URI(scheme, - uri.getUserInfo(), host, port, - null, uri.getQuery(), uri.getFragment()); - URI build = UriBuilder.fromUri(newUri).path(actualPath).build(); - requestContext.setUri(build); - if (measureTime && instance.gatherStatistics()) { - requestContext.setCallStatsCollector(instance); - } - requestContext.resume(); - } catch (URISyntaxException e) { - requestContext.resume(new IllegalArgumentException("Invalid URI", e)); - } - }, - requestContext::resume); + }, + requestContext::resume); + } catch (Throwable e) { + log.error("Error selecting service instance for serviceName: " + serviceName, e); + requestContext.resume(e); + } } } From 47845adf498155b23416062c1729583a96b7cf05 Mon Sep 17 00:00:00 2001 From: Matej Novotny Date: Thu, 4 Apr 2024 14:27:38 +0200 Subject: [PATCH 13/29] Mention ScheduledExecutorService in scheduler reference doc (cherry picked from commit e4ed465eafa7af91d1e4a1a15fa5271dfcd64405) --- docs/src/main/asciidoc/scheduler-reference.adoc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/src/main/asciidoc/scheduler-reference.adoc b/docs/src/main/asciidoc/scheduler-reference.adoc index b2374725ae3a1..ebfa3a4f34540 100644 --- a/docs/src/main/asciidoc/scheduler-reference.adoc +++ b/docs/src/main/asciidoc/scheduler-reference.adoc @@ -438,6 +438,23 @@ NOTE: By default, the scheduler is not started unless a `@Scheduled` business me NOTE: If the xref:quartz.adoc[Quartz extension] is present and the DB store type is used then it's not possible to pass a task instance to the job definition and a task class must be used instead. The Quartz API can be also used to schedule a job programmatically. +In certain cases, a more fine-grained approach might be needed which is why Quarkus also exposes `java.util.concurrent.ScheduledExecutorService` and `java.util.concurrent.ExecutorService` that can be injected as CDI beans. +However, these executors are used by other Quarkus extensions and therefore should be approached with caution. Furthermore, users are never allowed to shut these executors down manually. + +[source,java] +---- +class JobScheduler { + + @Inject + ScheduledExecutorService executor; + + void everySecondWithDelay() { + Runnable myRunnable = createMyRunnable(); + executor.scheduleAtFixedRate(myRunnable, 3, 1, TimeUnit.SECONDS); + } +} +---- + == Scheduled Methods and Testing It is often desirable to disable the scheduler when running the tests. From e179cef8cf3ac1fd277ab11db9c87e379973f7d4 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 4 Apr 2024 09:14:19 +0300 Subject: [PATCH 14/29] Use cache-control header to make sure health checks aren't cached Fixes: #39868 (cherry picked from commit 6f53e362aec269c030ec0e5a28f8ae65da57ae68) --- .../health/test/HealthCheckProducerDefaultScopeTest.java | 2 ++ .../smallrye/health/runtime/SmallRyeHealthHandlerBase.java | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/extensions/smallrye-health/deployment/src/test/java/io/quarkus/smallrye/health/test/HealthCheckProducerDefaultScopeTest.java b/extensions/smallrye-health/deployment/src/test/java/io/quarkus/smallrye/health/test/HealthCheckProducerDefaultScopeTest.java index 4233aa75967f1..0b3921302320d 100644 --- a/extensions/smallrye-health/deployment/src/test/java/io/quarkus/smallrye/health/test/HealthCheckProducerDefaultScopeTest.java +++ b/extensions/smallrye-health/deployment/src/test/java/io/quarkus/smallrye/health/test/HealthCheckProducerDefaultScopeTest.java @@ -31,10 +31,12 @@ void testHealth() { try { RestAssured.defaultParser = Parser.JSON; when().get("/q/health/ready").then() + .header("cache-control", "no-store") .body("status", is("UP"), "checks.status", hasItems("UP", "UP"), "checks.name", hasItems("alpha1", "bravo1")); when().get("/q/health/ready").then() + .header("cache-control", "no-store") .body("status", is("UP"), "checks.status", hasItems("UP", "UP"), "checks.name", hasItems("alpha1", "bravo2")); diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandlerBase.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandlerBase.java index 30dd03d3ca973..cc0bb85cce758 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandlerBase.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandlerBase.java @@ -59,7 +59,9 @@ private void doHandle(RoutingContext ctx, ManagedContext requestContext) { if (health.isDown()) { resp.setStatusCode(503); } - resp.headers().set(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8"); + resp.headers() + .set(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8") + .set(HttpHeaders.CACHE_CONTROL, "no-store"); Buffer buffer = Buffer.buffer(256); // this size seems to cover the basic health checks try (BufferOutputStream outputStream = new BufferOutputStream(buffer);) { reporter.reportHealth(outputStream, health); From 1a13f795d28ba75f7d7c2ca5272a783c2bc328a0 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Thu, 4 Apr 2024 14:28:06 +0300 Subject: [PATCH 15/29] Bump MINIMUM working mandrel/graalvm version to 22.3 Follow up to https://github.com/quarkusio/quarkus/pull/37828#issuecomment-1862796025 and https://github.com/quarkusio/quarkus/pull/39866#discussion_r1550072028 (cherry picked from commit 1b6033b0aeaf5f6c5afcc2d10d7192390571c5a2) --- .../src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java index deda3c9d1f965..734575f2f0333 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java @@ -181,7 +181,6 @@ public static final class Version implements Comparable { static final Version VERSION_21_3 = new Version("GraalVM 21.3", "21.3", Distribution.GRAALVM); static final Version VERSION_21_3_0 = new Version("GraalVM 21.3.0", "21.3.0", Distribution.GRAALVM); public static final Version VERSION_22_3_0 = new Version("GraalVM 22.3.0", "22.3.0", "17", Distribution.GRAALVM); - public static final Version VERSION_22_2_0 = new Version("GraalVM 22.2.0", "22.2.0", "17", Distribution.GRAALVM); public static final Version VERSION_23_0_0 = new Version("GraalVM 23.0.0", "23.0.0", "17", Distribution.GRAALVM); public static final Version VERSION_23_1_0 = new Version("GraalVM 23.1.0", "23.1.0", "21", Distribution.GRAALVM); public static final Version VERSION_24_0_0 = new Version("GraalVM 24.0.0", "24.0.0", "22", Distribution.GRAALVM); @@ -190,7 +189,7 @@ public static final class Version implements Comparable { * The minimum version of GraalVM supported by Quarkus. * Versions prior to this are expected to cause major issues. */ - public static final Version MINIMUM = VERSION_22_2_0; + public static final Version MINIMUM = VERSION_22_3_0; /** * The current version of GraalVM supported by Quarkus. * This version is the one actively being tested and is expected to give the best experience. From 8a44cd280e0b0703eba5817cd3e392ad62ad9032 Mon Sep 17 00:00:00 2001 From: George Gastaldi Date: Thu, 4 Apr 2024 12:21:53 -0300 Subject: [PATCH 16/29] Bump the `recommended-java-version` to 21 (cherry picked from commit dd0c2410286b82ec111be5e87f03024caff081a2) --- build-parent/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-parent/pom.xml b/build-parent/pom.xml index 4f3655320912b..0214c541a0941 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -54,7 +54,7 @@ ${maven.compiler.release} - 17 + 21