Chapter 1. Migrating applications to Red Hat build of Quarkus 3.15 As an application developer, you can migrate applications that are based on Red Hat build of Quarkus version 3.2 or later to version 3.15 by using either the quarkus CLI or Maven. Important The Quarkus CLI is intended for development purposes, including tasks such as creating, updating, and building Quarkus projects. However, Red Hat does not support using the Quarkus CLI in production environments. 1.1. Updating projects to the latest Red Hat build of Quarkus version To update your Red Hat build of Quarkus projects to the latest version, follow these steps, which are explained in detail later in this guide: Use the quarkus CLI or Maven commands to run automated update tasks. Consult the Changes that affect compatibility with earlier versions section to perform any manual update tasks. 1.1.1. Automatic updates Running the quarkus CLI or Maven commands triggers OpenRewrite recipes that upgrade project dependencies and source code. This automated approach provides a convenient and reliable way to update your projects. However, not all migration tasks are automated. If specific updates are not applied after running the quarkus update command or its Maven equivalent, consider the following possible reasons: The required migration task is not covered by the available OpenRewrite recipes. An extension your project depends on is incompatible with the latest Red Hat build of Quarkus version. 1.1.2. Manual updates Manual updates give you the flexibility and control to address any migration tasks to ensure your project aligns with your specific needs. Tasks that are not automated must be handled manually. For a list of the migration tasks required to update from the release to this one, see the Changes That Affect Compatibility with Earlier Versions section of this guide. Reviewing the migration guide for each release version between the current version of your application project and the version you're upgrading to is essential. This review process ensures you are fully informed and prepared for the update process. For example, if upgrading from version 3.8 to 3.15, you only need to review this guide. If you are upgrading from version 3.2 to 3.15, you also need to review the intermediate version of this guide: Migrating applications to Red Hat build of Quarkus 3.8 guide. Each task in this migration guide outlines the required changes and indicates whether they are automatically handled by the quarkus update command and its Maven equivalent. For additional background, see the Quarkus community Migration guides . 1.2. Using the quarkus CLI to update the project Update your Red Hat build of Quarkus projects by using the quarkus CLI. Important The Quarkus CLI is intended for development purposes, including tasks such as creating, updating, and building Quarkus projects. However, Red Hat does not support using the Quarkus CLI in production environments. Prerequisites An IDE JDK 17 or 21 installed and JAVA_HOME configured Apache Maven 3.8.6 or later Optional: To build native Linux executables , Red Hat build of Quarkus supports using the Red Hat build of Quarkus Native Builder image (quarkus/mandrel-for-jdk-21-rhel8) , which is based on GraalVM Mandrel . The quarkus CLI 3.15.3 A project based on Red Hat build of Quarkus version 3.2 or later Procedure Create a working branch for your project in your version control system. Install the latest version of the quarkus CLI by following the installation guide . Verify the installation by running the following command: quarkus -v 3.15.3 Important : Configure the extension registry client as instructed in the Configuring Red Hat build of Quarkus extension registry client section of the "Getting Started with Red Hat build of Quarkus" guide. In the terminal, navigate to your project directory. Update the project: quarkus update Optional: To update to a specific stream, use the --stream option followed by a specific version; for example: quarkus update --stream=3.15 Review the output from the update command for instructions and perform any suggested tasks. Use a diff tool to inspect all changes made during the update process. Manually perform any changes that were not handled by updating the project. For details, refer to the following Changes that affect compatibility with earlier versions section. Ensure the project builds without errors, all tests pass, and the application functions as expected before deploying to production. 1.3. Using Maven to update the project Update your Red Hat build of Quarkus projects by using Maven. Prerequisites An IDE JDK 17 or 21 installed and JAVA_HOME configured Apache Maven 3.8.6 or later Optional: To build native Linux executables , Red Hat build of Quarkus supports using the Red Hat build of Quarkus Native Builder image (quarkus/mandrel-for-jdk-21-rhel8) , which is based on GraalVM Mandrel . A project based on Red Hat build of Quarkus version 3.2 or later Procedure Create a working branch for your project in your version control system. Important : Configure the extension registry client as detailed in the Configuring Red Hat build of Quarkus extension registry client section of the "Getting Started with Red Hat build of Quarkus" guide. Open a terminal and navigate to your project directory. Ensure that the Red Hat build of Quarkus Maven plugin version is aligned with the latest supported version. Configure the project according to the Getting started with Red Hat build of Quarkus guide, and then run: mvn com.redhat.quarkus.platform:quarkus-maven-plugin:3.15.3.SP1-redhat-00002:update Optional: To update to a specific stream, use the -Dstream option followed by the desired version; for example: mvn com.redhat.quarkus.platform:quarkus-maven-plugin:3.15.3.SP1-redhat-00002:update -Dstream=3.15 Review the output from the update command for any instructions and perform the suggested tasks. Use a diff tool to examine all changes made during the update process. Manually perform any changes that were not handled by updating the project. For details, refer to the following Changes that affect compatibility with earlier versions section. Ensure the project builds without errors, all tests pass, and the application functions as expected before deploying to production. 1.4. Changes that affect compatibility with earlier versions This section describes changes in Red Hat build of Quarkus 3.15 that affect the compatibility of applications built with earlier product versions. Review these breaking changes and take the necessary steps to ensure that your applications continue functioning after updating them to Red Hat build of Quarkus 3.15. You can perform many of the updates listed in this section by running quarkus update or the equivalent Maven command. This triggers automated OpenRewrite recipes that update your project dependencies and source code to the latest Red Hat build of Quarkus version. However, not all migration tasks are automated. If specific updates aren't applied by the automated update, it might be because the required migration task isn't covered by the available OpenRewrite recipes or an extension your project relies on is incompatible with the latest version. In such cases, you need to perform the updates manually. Be sure to review the following items to identify and address any manual migration tasks. 1.4.1. Compatibility 1.4.1.1. Spring compatibility layer updated to align with Spring Boot 3 With Red Hat build of Quarkus 3.15, the quarkus-spring-data-rest-extension was upgraded to align with the latest Spring Boot 3 API updates. If you use the PagingAndSortingRepository interface in your code, this upgrade might introduce breaking changes. Previously, the PagingAndSortingRepository extended the CrudRepository , which allowed your custom repository to inherit the methods from the CrudRepository . To resolve any issues related to this change, you must update your custom repository to extend either ListCrudRepository or CrudRepository directly. This adjustment ensures continued access to the required methods and maintains compatibility with the updated architecture. 1.4.2. Core 1.4.2.1. Dev Services startup detection change In Red Hat build of Quarkus 3.15, the method for determining whether Dev Services should start has changed. Previously, to decide whether to start Dev Services, Red Hat build of Quarkus checked if a configuration property was defined without expanding it. However, this approach caused issues if the property expanded to an empty value. Now, Red Hat build of Quarkus first checks whether the expanded property is empty. This change might result in Dev Services starting unexpectedly where they didn't before, in cases when the expanded property ends up being empty. Most Dev Services start when a given property is not provided, for instance, the JDBC URL. Due to this change, you should adjust your configuration properties to include a default value, ensuring that the expanded property is not empty. For example, if you use the quarkus-test-oidc-server component to mock the OpenID Connect (OIDC) server, and your application.properties file contains: Change the property value to: This way, if keycloak.url is not defined, the default replaced-by-test-resource value prevents the property from expanding to an empty value, thereby avoiding the unintended startup of Dev Services. If a variable is not defined in an expression, the whole expression will be empty. Note For this particular example, this change is applied automatically by running quarkus update . However, for other use cases, you might need to apply the change manually. 1.4.2.2. GraalVM SDK updates Red Hat build of Quarkus 3.15 updates the GraalVM SDK dependencies to version 23.1.2, correcting an earlier oversight and ensuring compatibility with the latest GraalVM features. If you develop extensions with GraalVM substitutions, replace the org.graalvm.sdk:graal-sdk dependency with org.graalvm.sdk:nativeimage . The nativeimage artifact includes only the required classes for substitutions, making it more streamlined. You can apply this change by running the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. Important JDK 17 requirement: GraalVM SDK 23.1.2 requires a minimum of JDK 17 at runtime. 1.4.2.3. Infinispan 15 component upgrade In Red Hat build of Quarkus 3.15, the Infinispan 15 component is upgraded to version 15.0. In earlier releases, before Infinispan 15 integration, you ran queries by using the following .Query.java code: @Inject RemoteCache<String, Book> booksCache; ... QueryFactory queryFactory = Search.getQueryFactory(booksCache); Query query = queryFactory.create("from book_sample.Book"); List<Book> list = query.execute().list(); However, with this release, this code no longer works because RemoteCache is now an @ApplicationScoped proxy bean and Search.getQueryFactory raises a ClassCastException . To resolve this, remove the indirection by using the query method in the RemoteCache API as follows: @Inject RemoteCache<String, Book> booksCache; ... Query<Book> query = booksCache.<Book>query("from book_sample.Book"); List<Book> list = query.execute().list(); You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.2.4. Packaging configuration changes In Red Hat build of Quarkus 3.15, the following packaging-related properties have been renamed or changed. If you use the original properties in your configuration, they still work, but a warning is displayed. You can apply this change by running the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. Table 1.1. Update the following properties in your configuration Original names Current names quarkus.package.type For JAR builds, use quarkus.package.jar.type with a valid JAR type: fast-jar , uber-jar , mutable-jar , or legacy-jar (deprecated). For native builds, set quarkus.native.enabled to true . For native sources builds, also set quarkus.native.sources-only to true . You can also disable JAR building by setting quarkus.package.jar.enabled to false . quarkus.package.create-appcds quarkus.package.jar.appcds.enabled quarkus.package.appcds-builder-image quarkus.package.jar.appcds.builder-image quarkus.package.appcds-use-container quarkus.package.jar.appcds.use-container quarkus.package.compress-jar quarkus.package.jar.compress quarkus.package.filter-optional-dependencies quarkus.package.jar.filter-optional-dependencies quarkus.package.add-runner-suffix quarkus.package.jar.add-runner-suffix Note: This configuration property generally only applies when building uber-JARs. quarkus.package.user-configured-ignored-entries quarkus.package.jar.user-configured-ignored-entries quarkus.package.user-providers-directory quarkus.package.jar.user-providers-directory quarkus.package.included-optional-dependencies quarkus.package.jar.included-optional-dependencies quarkus.package.include-dependency-list quarkus.package.jar.include-dependency-list quarkus.package.decompiler.version , quarkus.package.vineflower.version No replacement; these properties are now ignored. quarkus.package.decompiler.enabled , quarkus.package.vineflower.enabled quarkus.package.jar.decompiler.enabled quarkus.package.decompiler.jar-directory , quarkus.package.vineflower.jar-directory quarkus.package.jar.decompiler.jar-directory quarkus.package.manifest.attributes.* quarkus.package.jar.manifest.attributes.* quarkus.package.manifest.sections.*.* quarkus.package.jar.manifest.sections.*.* quarkus.package.manifest.add-implementation-entries quarkus.package.jar.manifest.add-implementation-entries Update any code and configuration files to reflect these changes and stop warning messages during the build process. 1.4.2.5. ProfileManager and ProfileManager#getActiveProfile removed In Red Hat build of Quarkus 3.15, the deprecated ProfileManager class and ProfileManager#getActiveProfile method are removed because the ProfileManager did not handle multiple profiles. With this removal, the following configuration change is required: To retrieve an active profile, use the io.quarkus.runtime.configuration.ConfigUtils#getProfiles API. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.2.6. The quarkus-app directory is now created only for fast-jar packages In earlier releases, an unintended behavior was observed where a quarkus-app directory was always generated in the build system's output directory, regardless of the type of artifact produced. In Red Hat build of Quarkus 3.15, the build process creates the quarkus-app directory only for fast-jar packages, which is the default artifact type. If you configure the build for a different artifact type, the quarkus-app directory is not created. 1.4.2.7. Required adjustments for extension developers In Red Hat build of Quarkus 3.15, the extension annotation processor used to generate runtime files and configuration documentation has been redeveloped, offering more flexibility but with new constraints: Mixing the legacy @ConfigRoot with the new @ConfigMapping approach in the same module is no longer allowed. If you use only @ConfigMapping , you do not need to make any changes. For legacy @ConfigRoot , inform the annotation processor by adding the following to your maven-compiler-plugin configuration: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <path> <groupId>io.quarkus</groupId> <artifactId>quarkus-extension-processor</artifactId> <version>USD{quarkus.version}</version> </path> </annotationProcessorPaths> <compilerArgs> <arg>-AlegacyConfigRoot=true</arg> </compilerArgs> </configuration> </plugin> If no configuration annotations exist in the test classes, this flag can trigger warnings when compiling test classes. To avoid this, enable the annotation processor only for default-compile execution: <plugin> <artifactId>maven-compiler-plugin</artifactId> <executions> <execution> <id>default-compile</id> <configuration> <annotationProcessorPaths> <path> <groupId>io.quarkus</groupId> <artifactId>quarkus-extension-processor</artifactId> <version>USD{quarkus.version}</version> </path> </annotationProcessorPaths> <compilerArgs> <arg>-AlegacyConfigRoot=true</arg> </compilerArgs> </configuration> </execution> </executions> </plugin> Moving to the new @ConfigMapping interface is encouraged, but support for legacy @ConfigRoot classes is planned to continue for a while to ensure a smooth migration. Deprecation plans are planned to be announced at a later date. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.3. Data 1.4.3.1. Database version verified on startup With Red Hat build of Quarkus 3.15, the Hibernate ORM extension verifies that the database version it connects to at runtime is at least as high as the one configured at build time. This verification occurs even when the configuration relies on default settings targeting the minimum database versions supported by Red Hat build of Quarkus. This update aims to alert application developers aware if they try to use a database version that Hibernate ORM or Red Hat build of Quarkus no longer support. If you try to use a database version that is no longer supported, Red Hat build of Quarkus does not start and throws an exception. This change affects applications that rely on the following database versions: DB2 earlier than version 10.5 Derby earlier than version 10.15.2 Oracle database earlier than version 19.0 MariaDB earlier than version 10.6 Microsoft SQL Server earlier than version 13 (2016) MySQL earlier than version 8.0 PostgreSQL earlier than version 12.0 If you cannot upgrade the database to a supported version, you can still try to use it, although some features might not work. To continue using an earlier, unsupported database version, set the db-version explicitly and, if necessary, set the dialect also. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. For more information, see the following resources: Supported databases section of the Quarkus "Using Hibernate ORM and Jakarta Persistence" guide Hibernate ORM: Supported dialects Hibernate ORM: Community dialects 1.4.3.2. Dev Services default images updates In Red Hat build of Quarkus 3.15, the default images for several Dev Services have been updated to the following versions: PostgreSQL version 16 MySQL version 8.4 MongoDB version 7.0 Elasticsearch version 8.15 OpenSearch version 2.16 You can apply this change by running the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. To use a specific version or distribution of these services, you must manually override the default container image in your application properties. For more information, see the Configuring the image section of the Quarkus "Dev Services for Elasticsearch" guide. 1.4.3.3. Hibernate ORM auto-flush optimization In Red Hat build of Quarkus 3.15, the Hibernate Object/Relational Mapping (ORM) auto-flush feature is optimized. Now, by default, before running a Hibernate Query Language (HQL), Java Persistence Query Language (JPQL), or native query, Hibernate ORM flushes only pending changes to the database if it detects that these changes might impact the query results. In most cases, this optimization will improve the performance of your applications, such as with more efficient batching, however, the following issues might occur: If you are running a native query, auto-flushing requires you to specify relevant entity types on the query. For more information, see the Hibernate ORM user guide . If pending changes impact only the target tables of the foreign keys used in the query, but those target tables are not used in the query, auto flushing does not happen. If you want to revert to behavior and choose an alternative default value, the quarkus.hibernate-orm.flush.mode configuration property is introduced. Set this property to always : quarkus.hibernate-orm.flush.mode=always . You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. For more information, see the following resources: Hibernate ORM 6.6 migration guide Hibernate ORM 6.6 user guide 1.4.3.4. Hibernate ORM upgraded to version 6.6 In Red Hat build of Quarkus 3.15, Hibernate ORM extensions were upgraded to Hibernate ORM 6.6 and introduced the following breaking changes: Applications with certain forms of incorrect configuration, mapping, or queries might now also throw exceptions. Previously, they would issue only warnings or malfunctions. For example: An invalid creation attempt when merging an entity with a @GeneratedValue identifier or a @Version property set to a non-null value now fails. Previously, it created the entity in the database. For more information, see Merge versioned entity when row is deleted . Applying both @MappedSuperclass and @Embeddable on the same type is no longer allowed. For more information, see Explicit validation of annotated class types . Some features are now enabled by default, to avoid unexpected behaviors. For example: Embeddables with @Embeddable annotated subtypes now use discriminator-based inheritance by default. For more information, see link: Discriminator-based embeddable inheritance . In some instances, behavior was changed to comply with the Java Persistence API (JPA) specification. For more information, see Criteria:jakarta.persistence.criteria.Expression#as(Class) . For more information, see the following resources: Hibernate ORM 6.5 migration guide Hibernate ORM 6.6 migration guide Hibernate ORM 6.6 user guide 1.4.3.5. Hibernate Search database schema update for outbox-polling system tables The quarkus-hibernate-search-orm-outbox-polling extension relies on system tables in the database to which Hibernate ORM connects, and with Red Hat build of Quarkus 3.15, the schema of these system tables might change. If you use this extension, you need to migrate your database schema. For information about how to migrate your database schema, see the Outbox polling database tables section in the "Hibernate Search migration" guide. If you cannot update your database schema, apply the following settings to restore the defaults: For the default persistence unit, specify the following: quarkus.hibernate-search-orm.coordination.entity-mapping.agent.uuid-type=char quarkus.hibernate-search-orm.coordination.entity-mapping.outbox-event.uuid-type=char For named persistence units, specify the following: quarkus.hibernate-search-orm.<persistence-unit-name>.coordination.entity-mapping.agent.uuid-type=char quarkus.hibernate-search-orm.<persistence-unit-name>.coordination.entity-mapping.outbox-event.uuid-type=char You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.3.6. Panache annotation processor removed for Hibernate ORM, Hibernate Reactive, and MongoDB In Red Hat build of Quarkus 3.15, the io.quarkus:quarkus-panache-common annotation processor has been removed because it is no longer required for externally defined entities when using Hibernate ORM with Panache, Hibernate Reactive with Panache, or MongoDB with Panache. In earlier releases, this annotation processor was automatically run when found in the classpath. If you had overridden the set of annotation processors in your build tool, you needed to add it explicitly. Remove all references to io.quarkus:quarkus-panache-common from the annotation processor list. You can apply this change by running the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. Maven users Find and remove the io.quarkus:quarkus-panache-common annotation processor from your pom.xml file: <build> <plugins> <!-- other plugins --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.13.0</version> <!-- Necessary for proper dependency management in annotationProcessorPaths --> <configuration> <annotationProcessorPaths> <path> <groupId>io.quarkus</groupId> <artifactId>quarkus-panache-common</artifactId> </path> </annotationProcessorPaths> </configuration> </plugin> <!-- other plugins --> </plugins> </build> Gradle users For Gradle builds, find and remove the io.quarkus:quarkus-panache-common annotation processor from your build.gradle file: dependencies { annotationProcessor "io.quarkus:quarkus-panache-common" } 1.4.4. Messaging 1.4.4.1. Changes to execution mode for synchronous methods in Quarkus Messaging In Red Hat build of Quarkus 3.15, the execution mode for synchronous methods in Quarkus Messaging extensions now defaults to worker threads. In earlier versions, these methods ran on the Vert.x event loop (I/O thread). For example, the following processing method is now called by default on a worker thread instead of the Vert.x I/O thread: package org.acme; import org.eclipse.microprofile.reactive.messaging.Incoming; import org.eclipse.microprofile.reactive.messaging.Outgoing; @Incoming("source") @Outgoing("sink") public Result process(int payload) { return new Result(payload); } To revert to the earlier behavior, you can use the quarkus.messaging.blocking.signatures.execution.mode configuration property. Possible values are: worker (default) event-loop (earlier behavior) virtual-thread You can also adjust the execution mode on a per-method basis by using the @Blocking and @NonBlocking annotations: package org.acme; import io.smallrye.common.annotation.NonBlocking; import org.eclipse.microprofile.reactive.messaging.Incoming; @Incoming("source") @NonBlocking public void consume(int payload) { // called on I/O thread } By annotating the method with @NonBlocking , you ensure it is called on the Vert.x event loop (I/O thread). Review your messaging methods to ensure they run in the required execution mode, and update your code or configuration as needed. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.4.2. SmallRye Reactive Messaging extensions renamed to Quarkus Messaging In Red Hat build of Quarkus 3.15, the SmallRye Reactive Messaging extensions have been renamed to quarkus-messaging-* to reflect their support for both reactive and blocking workloads. Maven relocations have been implemented. You can apply this change by running the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. Replace all instances of the old extension names in your projects with the new names. Renamed extensions The following extensions have been renamed: Old Name New Name quarkus-smallrye-reactive-messaging quarkus-messaging quarkus-smallrye-reactive-messaging-amqp quarkus-messaging-amqp quarkus-smallrye-reactive-messaging-kafka quarkus-messaging-kafka quarkus-smallrye-reactive-messaging-mqtt quarkus-messaging-mqtt quarkus-smallrye-reactive-messaging-pulsar quarkus-messaging-pulsar quarkus-smallrye-reactive-messaging-rabbitmq quarkus-messaging-rabbitmq The configuration root has also been updated from quarkus.smallrye-reactive-messaging. to quarkus.messaging. . An automatic fallback mechanism is in place to revert to the old configuration properties, if necessary. Impact on extension developers If you are an extension developer, note that the following deployment-related artifacts have also been renamed: Old Name New Name quarkus-smallrye-reactive-messaging-deployment quarkus-messaging-deployment quarkus-smallrye-reactive-messaging-kotlin quarkus-messaging-kotlin quarkus-smallrye-reactive-messaging-amqp-deployment quarkus-messaging-amqp-deployment quarkus-smallrye-reactive-messaging-kafka-deployment quarkus-messaging-kafka-deployment quarkus-smallrye-reactive-messaging-mqtt-deployment quarkus-messaging-mqtt-deployment quarkus-smallrye-reactive-messaging-pulsar-deployment quarkus-messaging-pulsar-deployment quarkus-smallrye-reactive-messaging-rabbitmq-deployment quarkus-messaging-rabbitmq-deployment Update your code and configurations to reflect these changes. 1.4.5. Observability 1.4.5.1. All quarkus.opentelemetry.* configuration properties removed In Red Hat build of Quarkus 3.15, all configuration properties under the quarkus.opentelemetry.* namespace have been removed. These properties were deprecated and maintained for backward compatibility in versions 3.2 and 3.8. Because they are now removed in 3.15, you must make the following changes to migrate your applications: Update all properties from the quarkus.opentelemetry. namespace to the quarkus.otel. namespace so they align with the OpenTelemetry Java autoconfigure conventions . Update the sampler property from quarkus.opentelemetry.tracer.sampler to quarkus.otel.traces.sampler . The parent-based sampler property quarkus.opentelemetry.tracer.sampler.parent-based has been removed. To mark the sampler as parent-based, specify it directly in the quarkus.otel.traces.sampler property, as shown below. Table 1.2. Value mapping from the original to the new sampler configuration Old value New value New value (parent-based) on always_on parentbased_always_on off always_off parentbased_always_off ratio traceidratio parentbased_traceidratio Update your code and configurations to use these new properties and values. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.5.2. OpenTelemetry io.opentelemetry.extension.annotations.WithSpan annotation removed In Red Hat build of Quarkus 3.15, the deprecated annotation io.opentelemetry.extension.annotations.WithSpan has been removed. Update your code to use the new io.opentelemetry.instrumentation.annotations.WithSpan annotation. Review and change any configurations or code that rely on the old annotation to ensure compatibility with this update. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.5.3. OpenTelemetry new semantic conventions for HTTP In Red Hat build of Quarkus 3.15, the OpenTelemetry (OTel) SDK has been upgraded to version 1.39.0 and instrumentation to version 2.5.0. This upgrade enforces the new conventions defined in the OpenTelemetry HTTP semantic convention stability migration . It also completes the removal of the deprecated standards. Update any code or configurations that depend on those conventions. Additionally, the quarkus.otel.semconv-stability.opt-in system property has been removed because opting-in is no longer supported. Update any code or configurations that depend on this property. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.5.4. OpenTelemetry REST client span name changes In Red Hat build of Quarkus 3.15, the OpenTelemetry (OTel) REST client span names now include both the HTTP request method and path; for example, GET /hello . Earlier REST client span names included only the HTTP method. Update any code or configurations that depend on the specific format of REST client span names. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.5.5. OpenTelemetry (OTel) span names generated by database operations changed In Red Hat build of Quarkus 3.15, the span names generated by database operations have changed due to updates in the libraries we use. For example, before this change, the old span name for creating a database table was DB Query . Now, with this change, the new span name is CREATE TABLE {table_name} . This new naming convention provides more descriptive and meaningful span names that accurately reflect the specific database operations performed. As a result, you might notice different names for spans generated by database operations in your observability tools. Review and update any custom monitoring configurations, alerts, or dashboards that rely on the old span names to accommodate the new naming convention. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. For more information about the database span naming conventions and best practices, see the OpenTelemetry Database Span Semantic Conventions specification. 1.4.5.6. SmallRye health configuration properties relocated In earlier versions, some configuration properties were incorrectly located under the quarkus.health configuration root. In Red Hat build of Quarkus 3.15, those properties have relocated to the quarkus.smallrye-health configuration root for consistency: quarkus.health.extensions.enabled has been moved to quarkus.smallrye-health.extensions.enabled quarkus.health.openapi.included has been moved to quarkus.smallrye-health.openapi.included In Red Hat build of Quarkus 3.15, the properties with the old configuration roots have been deprecated and are planned to be removed in a future release. Update any code or configurations to use the new property locations. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.6. Security 1.4.6.1. Keystore and truststore default format changed With Red Hat build of Quarkus 3.15, Java Keystroke (JKS) is no longer the default keystore and truststore format. Instead, Red Hat build of Quarkus determines the format based on the file extension, as follows: .pem , .crt , and .key files are read as Privacy Enhanced Mail (PEM) certificates and keys .jks , .keystore , and .truststore files are read as JKS keystores and truststores .p12 , .pkcs12 , and .pfx files are read as PKCS12 keystores and truststores If your file does not use one of these extensions, you must set the file format. For example, to specify the JKS format, set the following configuration values: quarkus.http.ssl.certificate.key-store-file-type=JKS quarkus.http.ssl.certificate.trust-store-file-type=JKS Note To specify P12 or PEM formats, set P12 or PEM instead of JKS. 1.4.6.2. OpenID Connect (OIDC) UserInfo acquisition enforced when UserInfo is injected In Red Hat build of Quarkus 3.15, the quarkus.oidc.authentication.user-info-required property is now automatically set to true when io.quarkus.oidc.UserInfo is injected into a REST endpoint. This change removes the need to configure this property manually, because UserInfo is typically injected when its use is intended. However, in more complex setups where multiple OIDC tenants secure endpoints, and some tenants do not support UserInfo , this change might lead to tenant initialization failures. This happens only when a tenant that does not support UserInfo is still configured to acquire it, potentially causing requests secured by that tenant to fail. To avoid such failures in multi-tenant setups, set the tenant-specific quarkus.oidc.<tenant-id>.authentication.user-info-required property to false for tenants that do not support UserInfo . This ensures that only tenants that support UserInfo enforce its acquisition. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.7. Tooling 1.4.7.1. JUnit Pioneer version no longer enforced In Red Hat build of Quarkus 3.15, the Quarkus BOM no longer enforces the version of the org.junit-pioneer:junit-pioneer dependency. If you are using this dependency in your project, you must explicitly specify its version in your build files. To avoid any build issues, define the version in your pom.xml or build.gradle files; for example: pom.xml <properties> ... <junit-pioneer.version>2.2.0</junit-pioneer.version> ... </properties> You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.8. Web 1.4.8.1. Quarkus REST: Adding web links programmatically In Red Hat build of Quarkus 3.15, for Quarkus REST (formerly RESTEasy Reactive), the signatures of the Hypertext Application Language (HAL) wrapper classes have been modified to include the type of elements in the collection: HalCollectionWrapper<T> HalEntityWrapper<T> Add the appropriate type argument wherever you use the HAL wrapper classes in your code. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. New preferred method for creating HAL wrappers The preferred approach for creating HAL wrapper classes has changed. Instead of using constructors, use the helper methods provided by the io.quarkus.hal.HalService bean. For example: @Path("/records") public class RecordsResource { @Inject HalService halService; @GET @Produces({ MediaType.APPLICATION_JSON, RestMediaType.APPLICATION_HAL_JSON }) @RestLink(rel = "list") public HalCollectionWrapper<Record> getAll() { List<Record> list = // ... HalCollectionWrapper<Record> halCollection = halService.toHalCollectionWrapper( list, "collectionName", Record.class); // ... return halCollection; } @GET @Produces({ MediaType.APPLICATION_JSON, RestMediaType.APPLICATION_HAL_JSON }) @Path("/{id}") @RestLink(rel = "self") @InjectRestLinks(RestLinkType.INSTANCE) public HalEntityWrapper<Record> get(@PathParam("id") int id) { Record entity = // ... HalEntityWrapper<Record> halEntity = halService.toHalWrapper(entity); // ... return halEntity; } } Although creating HAL wrappers by using constructors still works, that approach might be deprecated in a future version. Therefore, start using the helper methods exposed by the HalService bean. For more information, see the Web Links support section of the "Quarkus REST" guide. 1.4.8.2. Quarkus REST filters on non-REST paths In earlier releases, Quarkus REST (formerly RESTEasy Reactive) filters ran even when the requested resource was not a REST resource. In Red Hat build of Quarkus 3.15, that behavior has changed. Now, Quarkus REST filters run only on REST resources. Note Quarkus REST is a Jakarta REST (formerly JAX-RS) implementation built from the ground up to work on Quarkus's common Vert.x layer. It is fully reactive and highly optimized for build-time processing. If you need your filters to apply to non-Quarkus REST resources, you can do so by adding a custom ExceptionMapper for NotFoundException , as shown in the following example: package io.quarkus.resteasy.reactive.server.test.customproviders; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.Provider; @Provider public class NotFoundExeptionMapper implements ExceptionMapper<NotFoundException> { @Override public Response toResponse(NotFoundException exception) { return Response.status(404).build(); } } With this ExceptionMapper , Quarkus REST handles "Not Found" resources, allowing filters to run as expected. Earlier, filters always ran on non-REST resources, which made it difficult for other extensions to handle "Not Found" scenarios effectively. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.8.3. Qute REST integration update: TemplateInstance is blocking by default In Red Hat build of Quarkus 3.15, the io.quarkus.qute.TemplateInstance class is no longer registered as a non-blocking type. As a result, if a Jakarta REST (formerly JAX-RS) resource method returns a TemplateInstance object, it is now considered blocking by default. To restore the earlier non-blocking behavior, apply the @io.smallrye.common.annotation.NonBlocking annotation to the resource method. Note This change only affects applications using the Quarkus REST (formerly RESTEasy Reactive) extension, quarkus-rest . You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. 1.4.8.4. RESTEasy Reactive extensions renamed to Quarkus REST In Red Hat build of Quarkus 3.15, the RESTEasy Reactive extensions have been renamed to quarkus-rest-* to reflect their support for both reactive and blocking workloads. Maven relocations have been implemented. You can apply this change by running the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. Replace all instances of the old extension names in your projects with the new names. Most of the new extension names follow this naming convention: Extensions ending with -rest use Quarkus REST (formerly RESTEasy Reactive). Extensions ending with -resteasy use RESTEasy Classic. Renamed extensions The following extensions have been renamed: Old Name New Name quarkus-resteasy-reactive quarkus-rest quarkus-resteasy-reactive-jackson quarkus-rest-jackson quarkus-resteasy-reactive-jaxb quarkus-rest-jaxb quarkus-resteasy-reactive-jsonb quarkus-rest-jsonb quarkus-resteasy-reactive-kotlin quarkus-rest-kotlin quarkus-resteasy-reactive-kotlin-serialization quarkus-rest-kotlin-serialization quarkus-resteasy-reactive-links quarkus-rest-links quarkus-resteasy-reactive-qute quarkus-rest-qute quarkus-resteasy-reactive-servlet quarkus-rest-servlet quarkus-rest-client-reactive quarkus-rest-client quarkus-rest-client-reactive-jackson quarkus-rest-client-jackson quarkus-rest-client-reactive-jaxb quarkus-rest-client-jaxb quarkus-rest-client-reactive-jsonb quarkus-rest-client-jsonb quarkus-rest-client-reactive-kotlin-serialization quarkus-rest-client-kotlin-serialization quarkus-jaxrs-client-reactive quarkus-rest-client-jaxrs quarkus-keycloak-admin-client quarkus-keycloak-admin-resteasy-client quarkus-keycloak-admin-client-reactive quarkus-keycloak-admin-rest-client quarkus-oidc-client-filter quarkus-resteasy-client-oidc-filter quarkus-oidc-client-reactive-filter quarkus-rest-client-oidc-filter quarkus-oidc-token-propagation quarkus-resteasy-client-oidc-token-propagation quarkus-oidc-token-propagation-reactive quarkus-rest-client-oidc-token-propagation quarkus-csrf-reactive quarkus-rest-csrf quarkus-spring-web-resteasy-classic quarkus-spring-web-resteasy quarkus-spring-web-resteasy-reactive quarkus-spring-web-rest The configuration roots have also been updated: Old configuration root New configuration root quarkus.resteasy-reactive.* quarkus.rest.* quarkus.rest-client-reactive.* quarkus.rest-client.* quarkus.oidc-client-reactive-filter.* quarkus.rest-client-oidc-filter.* quarkus.oidc-token-propagation-reactive.* quarkus.rest-client-oidc-token-propagation.* quarkus.csrf-reactive.* quarkus.rest-csrf.* quarkus.oidc-client-filter.* quarkus.resteasy-client-oidc-filter.* quarkus.oidc-token-propagation.* quarkus.resteasy-client-oidc-token-propagation.* An automatic fallback mechanism is in place to revert to the old configuration properties if necessary. Impact on extension developers If you are an extension developer, note that the following deployment-related artifacts have also been renamed: Old Name New Name quarkus-resteasy-reactive-deployment quarkus-rest-deployment quarkus-resteasy-reactive-jackson-common quarkus-rest-jackson-common quarkus-resteasy-reactive-jackson-common-deployment quarkus-rest-jackson-common-deployment quarkus-resteasy-reactive-jackson-deployment quarkus-rest-jackson-deployment quarkus-resteasy-reactive-jaxb-common quarkus-rest-jaxb-common quarkus-resteasy-reactive-jaxb-common-deployment quarkus-rest-jaxb-common-deployment quarkus-resteasy-reactive-jaxb-deployment quarkus-rest-jaxb-deployment quarkus-resteasy-reactive-jsonb-common quarkus-rest-jsonb-common quarkus-resteasy-reactive-jsonb-common-deployment quarkus-rest-jsonb-common-deployment quarkus-resteasy-reactive-jsonb-deployment quarkus-rest-jsonb-deployment quarkus-resteasy-reactive-kotlin-deployment quarkus-rest-kotlin-deployment quarkus-resteasy-reactive-kotlin-serialization-common quarkus-rest-kotlin-serialization-common quarkus-resteasy-reactive-kotlin-serialization-common-deployment quarkus-rest-kotlin-serialization-common-deployment quarkus-resteasy-reactive-kotlin-serialization-deployment quarkus-rest-kotlin-serialization-deployment quarkus-resteasy-reactive-links-deployment quarkus-rest-links-deployment quarkus-resteasy-reactive-qute-deployment quarkus-rest-qute-deployment quarkus-resteasy-reactive-server-common quarkus-rest-server-common quarkus-resteasy-reactive-server-spi-deployment quarkus-rest-server-spi-deployment quarkus-resteasy-reactive-servlet-deployment quarkus-rest-servlet-deployment quarkus-resteasy-reactive-common quarkus-rest-common quarkus-resteasy-reactive-common-deployment quarkus-rest-common-deployment quarkus-rest-client-reactive-deployment quarkus-rest-client-deployment quarkus-rest-client-reactive-jackson-deployment quarkus-rest-client-jackson-deployment quarkus-rest-client-reactive-jaxb-deployment quarkus-rest-client-jaxb-deployment quarkus-rest-client-reactive-jsonb-deployment quarkus-rest-client-jsonb-deployment quarkus-rest-client-reactive-kotlin-serialization-deployment quarkus-rest-client-kotlin-serialization-deployment quarkus-rest-client-reactive-spi-deployment quarkus-rest-client-spi-deployment quarkus-jaxrs-client-reactive-deployment quarkus-rest-client-jaxrs-deployment quarkus-keycloak-admin-client-deployment quarkus-keycloak-admin-resteasy-client-deployment quarkus-keycloak-admin-client-reactive-deployment quarkus-keycloak-admin-rest-client-deployment quarkus-oidc-client-filter-deployment quarkus-resteasy-client-oidc-filter-deployment quarkus-oidc-client-reactive-filter-deployment quarkus-rest-client-oidc-filter-deployment quarkus-oidc-token-propagation-deployment quarkus-resteasy-client-oidc-token-propagation-deployment quarkus-oidc-token-propagation-reactive-deployment quarkus-rest-client-oidc-token-propagation-deployment quarkus-csrf-reactive-deployment quarkus-rest-csrf-deployment quarkus-spring-web-resteasy-classic-deployment quarkus-spring-web-resteasy-deployment quarkus-spring-web-resteasy-reactive-deployment quarkus-spring-web-rest-deployment 1.4.8.5. WebJar Locator extension renamed to Web-dependency-locator In Red Hat build of Quarkus 3.15, the quarkus-webjars-locator extension is renamed to quarkus-web-dependency-locator and is also enhanced to include mvnpm (Maven NPM) and importmaps . Update your code and configurations to use the new extension name. You must apply this change manually. It is not covered by the automated update described in the Migrating applications to Red Hat build of Quarkus 3.15 guide. For more information, see the Quarkus Web dependency locator guide. 1.5. Additional resources Release notes for Red Hat build of Quarkus version 3.15

Commands:
quarkus -v 3.15.3
quarkus update
quarkus update --stream=3.15
mvn com.redhat.quarkus.platform:quarkus-maven-plugin:3.15.3.SP1-redhat-00002:update
mvn com.redhat.quarkus.platform:quarkus-maven-plugin:3.15.3.SP1-redhat-00002:update -Dstream=3.15
%test.quarkus.oidc.auth-server-url=USD{keycloak.url}/realms/quarkus/
%test.quarkus.oidc.auth-server-url=USD{keycloak.url:replaced-by-test-resource}/realms/quarkus/
@Inject RemoteCache<String, Book> booksCache; ... QueryFactory queryFactory = Search.getQueryFactory(booksCache); Query query = queryFactory.create("from book_sample.Book"); List<Book> list = query.execute().list();
@Inject RemoteCache<String, Book> booksCache; ... Query<Book> query = booksCache.<Book>query("from book_sample.Book"); List<Book> list = query.execute().list();
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <path> <groupId>io.quarkus</groupId> <artifactId>quarkus-extension-processor</artifactId> <version>USD{quarkus.version}</version> </path> </annotationProcessorPaths> <compilerArgs> <arg>-AlegacyConfigRoot=true</arg> </compilerArgs> </configuration> </plugin>
<plugin> <artifactId>maven-compiler-plugin</artifactId> <executions> <execution> <id>default-compile</id> <configuration> <annotationProcessorPaths> <path> <groupId>io.quarkus</groupId> <artifactId>quarkus-extension-processor</artifactId> <version>USD{quarkus.version}</version> </path> </annotationProcessorPaths> <compilerArgs> <arg>-AlegacyConfigRoot=true</arg> </compilerArgs> </configuration> </execution> </executions> </plugin>
<build> <plugins> <!-- other plugins --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.13.0</version> <!-- Necessary for proper dependency management in annotationProcessorPaths --> <configuration> <annotationProcessorPaths> <path> <groupId>io.quarkus</groupId> <artifactId>quarkus-panache-common</artifactId> </path> </annotationProcessorPaths> </configuration> </plugin> <!-- other plugins --> </plugins> </build>
dependencies { annotationProcessor "io.quarkus:quarkus-panache-common" }
package org.acme; import org.eclipse.microprofile.reactive.messaging.Incoming; import org.eclipse.microprofile.reactive.messaging.Outgoing; @Incoming("source") @Outgoing("sink") public Result process(int payload) { return new Result(payload); }
package org.acme; import io.smallrye.common.annotation.NonBlocking; import org.eclipse.microprofile.reactive.messaging.Incoming; @Incoming("source") @NonBlocking public void consume(int payload) { // called on I/O thread }
<properties> <junit-pioneer.version>2.2.0</junit-pioneer.version> </properties>
@Path("/records") public class RecordsResource { @Inject HalService halService; @GET @Produces({ MediaType.APPLICATION_JSON, RestMediaType.APPLICATION_HAL_JSON }) @RestLink(rel = "list") public HalCollectionWrapper<Record> getAll() { List<Record> list = // HalCollectionWrapper<Record> halCollection = halService.toHalCollectionWrapper( list, "collectionName", Record.class); // return halCollection; } @GET @Produces({ MediaType.APPLICATION_JSON, RestMediaType.APPLICATION_HAL_JSON }) @Path("/{id}") @RestLink(rel = "self") @InjectRestLinks(RestLinkType.INSTANCE) public HalEntityWrapper<Record> get(@PathParam("id") int id) { Record entity = // HalEntityWrapper<Record> halEntity = halService.toHalWrapper(entity); // return halEntity; } }
package io.quarkus.resteasy.reactive.server.test.customproviders; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.Provider; @Provider public class NotFoundExeptionMapper implements ExceptionMapper<NotFoundException> { @Override public Response toResponse(NotFoundException exception) { return Response.status(404).build(); } }