Skip to content

Migration Guide 3.0

George Gastaldi edited this page Mar 30, 2023 · 37 revisions
Table of Contents

CDI

Interceptor annotations on private methods

Adding a CDI interceptor annotation such as @Transactional to a private method was never supported, and used to result in a warning in logs because the annotation is ignored.

When such an annotation is ignored, Quarkus will now trigger a build failure instead:

javax.enterprise.inject.spi.DeploymentException: @Transactional will have no effect on method com.acme.MyBean.myMethod() because the method is private. [...]

Ideally you should remove such annotations since they are ignored, but if that’s not possible, set the configuration property quarkus.arc.fail-on-intercepted-private-method to false to revert to the previous behavior (warnings in logs).

Removed @AlternativePriority

The @AlternativePriority annotation has been deprecated since Quarkus 2.6 and is removed in Quarkus 3.0. Replace all usages with the 2 annotations @Alternative and @Priority.

Before:

@AlternativePriority(1)

After:

@Alternative
@Priority(1)

It is preferable to use jakarta.annotation.Priority, but if you need to maintain compatibility with Quarkus 2.x and 3.x through mechanical transformation, you can use io.quarkus.arc.Priority as well. These 2 annotations are equivalent. Note that the io.quarkus.arc.Priority annotation is getting deprecated in Quarkus 3.0 and will be removed in the future.

RESTEasy Reactive

  • Class org.jboss.resteasy.reactive.server.core.multipart.MultipartFormDataOutput has been moved to org.jboss.resteasy.reactive.server.multipart.MultipartFormDataOutput

  • Class org.jboss.resteasy.reactive.server.core.multipart.PartItem has been moved to ` org.jboss.resteasy.reactive.server.multipart.PartItem`

  • Class org.jboss.resteasy.reactive.server.core.multipart.FormData.FormValue has been moved to org.jboss.resteasy.reactive.server.multipart.FormValue

REST Client

The REST Client no longer uses the server specific MessageBodyReader and MessageBodyWriter classes associated with Jackson (which used to be the case, but was unintentional). The result is that applications that use both quarkus-resteasy-reactive-jackson and quarkus-rest-client-reactive now have to include quarkus-rest-client-reactive-jackson

JPA / Hibernate ORM

Moved to Hibernate ORM 6.2

Quarkus now depends on Hibernate ORM 6.2 instead of Hibernate ORM 5.6.

This implies a noticeable amount of backwards-incompatible changes, be it in APIs, behavior, or database schema expectations. In particular, but not only:

Refer to this dedicated guide for more information.

Using persistence.xml files and quarkus.hibernate-orm.* configuration properties in the same application will fail

When configuring the Hibernate ORM extension through both a persistence.xml file and quarkus.hibernate-orm. properties in application.properties, Quarkus used to ignore quarkus.hibernate-orm. properties, even though documentation stated the application would fail to start.

Quarkus will now fail as expected when it can detect such situations.

You can still chose between persistence.xml and quarkus.hibernate-orm.* properties:

  • To ignore persistence.xml files, set the configuration property quarkus.hibernate-orm.persistence-xml.ignore to true.

  • To use persistence.xml files, remove all quarkus.hibernate-orm.* properties from application.properties.

Configuration property quarkus.hibernate-orm.globally-quoted-identifiers is deprecated

The default ID generation optimizer is now pooled-lo

In order to mitigate some incompatibilities caused by the migration to Hibernate ORM 6, and also to simplify sequence reset requirements in import scripts in general, the default ID generation optimizer has changed from pooled to pooled-lo.

This change is backwards-compatible, but if you need to revert to the pooled optimizer, just set quarkus.hibernate-orm.id.optimizer.default = pooled.

Hibernate Reactive

Moved to Hibernate Reactive 2

Quarkus now depends on Hibernate Reactive 2 instead of Hibernate Reactive 1.

This implies a noticeable amount of backwards-incompatible changes, be it in behavior or database schema expectations.

Most of the changes are related to Hibernate Reactive 2 depending on Hibernate ORM 6.2 instead of Hibernate ORM 5.6. Refer to this dedicated guide for more information about the migration from Hibernate ORM 5.6 to 6.2 (and thus, from Hibernate Reactive 1 to 2).

Session injection

It is no longer possible to inject a Mutiny.Session in a CDI bean. The main reason for this change is that the lifecycle of a reactive session does not fit the lifecycle of the CDI request context. And this mismatch can result in tricky errors. Users are encouraged to inject a Mutiny.SessionFactory instead and control the session lifecycle through the SessionFactory#withSession() and SessionFactory#withTransaction() methods.

The default ID generation optimizer is now pooled-lo

In order to mitigate some incompatibilities caused by the migration to Hibernate Reactive 2, and also to simplify sequence reset requirements in import scripts in general, the default ID generation optimizer has changed from pooled to pooled-lo.

This change is backwards-compatible, but if you need to revert to the pooled optimizer, just set quarkus.hibernate-orm.id.optimizer.default = pooled.

Hibernate Reactive Panache

This extension has undergone extensive refactoring. However, most of the changes do not affect the API.

Sessions and Transactions

Two major internal changes include:

  • The current reactive Mutiny.Session is no longer stored in the CDI request context,

  • A Panache entity method execution is not offloaded on the current Vert.x context anymore.

The consequence of these changes is that a user might need to take care of marking reactive session boundaries. For example most of the methods of a Hibernate Reactive Panache entity must be invoked within the scope of a reactive Mutiny.Session. In some cases, the session is opened automatically on demand. For example, if a Panache entity method is invoked in a JAX-RS resource method in an application that includes the quarkus-resteasy-reactive extension. For other cases, there are both a declarative and a programmatic way to ensure the session is opened. You can annotate a CDI business method that returns Uni with the @WithSession annotation. The method will be intercepted and the returned Uni will be triggered within a scope of a reactive session. Alternatively, you can use the Panache.withSession() method to achieve the same effect.

Also make sure to wrap methods that modify the database or involve multiple queries within a transaction. You can annotate a CDI business method that returns Uni with the @WithTransaction annotation. The method will be intercepted and the returned Uni is triggered within a transaction boundary. Alternatively, you can use the Panache.withTransaction() method for the same effect.

The @ReactiveTransactional annotation is deprecated and can only be used for methods that return Uni; this is validated at build time. Users are encouraged to use @WithTransaction instead.

Support of Multi

Neither Hibernate Reactive nor reactive SQL clients support streaming. Furthermore, we are not able to provide a Panache#withTransaction() alternative for io.smallrye.mutiny.Multi without bypassing the Hibernate Reactive API. Therefore, we decided to remove the stream() methods from the PanacheEntityBase, PanacheQuery and PanacheRepositoryBase. You can replace the code like MyEntity.<MyEntity> streamAll() with something similar to MyEntity.<MyEntity> listAll()).toMulti().chain(list → Multi.createFrom().iterable(list)) (which is by the way very similar to the original internal implementation).

Kubernetes/OpenShift

Removed deprecated properties

Deprecated Property Property to use

quarkus.kubernetes.expose

quarkus.kubernetes.ingress.expose

quarkus.openshift.expose

quarkus.openshift.route.expose

quarkus.kubernetes.host

quarkus.kubernetes.ingress.host

quarkus.openshift.host

quarkus.openshift.route.host

quarkus.kubernetes.group

quarkus.kubernetes.part-of

quarkus.openshift.group

quarkus.openshift.part-of

Plus, properties without the quarkus. prefix will now be ignored. For example, before this version, we could add the property kubernetes.name and this property was mapped to quarkus.kubernetes.name. After this version, we’re not going to do this any longer to avoid issues like https://github.com/quarkusio/quarkus/issues/30850.

The HTTPS container port is added to generated Pod resources

  • Before, the generated container and service resources were only mapping the HTTP port of the Quarkus application. Now, the HTTPS port is also being mapped unless SSL is explicitly disabled using the property quarkus.http.insecure-requests=disabled.

  • New property to select the port name to be used by the generated Ingress resource: quarkus.kubernetes.ingress.target-port=https (by default, its value is http).

In the 2.16.0 and 2.16.1 releases, in OIDC web-app applications, OIDC session cookie had a SameSite attribute set to Strict by default. However SameSite=Strict introduced unpredictability in the way the session cookie can be handled by different browsers. Therefore starting from 3.0, the session cookie will again have a SameSite=Lax attribute set by default.

If you do have a 2.16.0 or 2.16.1 based application working with the session cookie having SameSite=Strict attribute, then please add the following configuration: quarkus.oidc.authentication.cookie-same-site=strict

SmallRye Reactive Messaging

vertx-kafka-client dependency removed

Since the 2.12.0 release the vertx-kafka-client dependency from the smallrye-reactive-messaging-kafka extension is marked for removal. While not used for client implementations, this dependency provided default Kafka serdes for io.vertx.core.buffer.Buffer, io.vertx.core.json.JsonObject and io.vertx.core.json.JsonArray types, from the io.vertx.kafka.client.serialization package.

The 3.0 release removes this dependency. Serdes mentioned above are still provided from the io.quarkus.kafka.client.serialization package.

Split package resolution

SmallRye Reactive Messaging proposes an in-memory connector for testing purposes.

The usage of this connector caused a split-package issue because its classes are provided from the io.smallrye.reactive.messaging.providers.connectors. This is resolved by moving these classes to io.smallrye.reactive.messaging.memory package.

JAXB

The JAXB extension automatically detects the classes that are using JAXB annotations and registers these classes into the default JAXBContext. This default JAXBContext instance is validated at runtime when used, so if there are issues or conflicts with the classes and JAXB, you will get a JAXB exception with a proper description to help you troubleshoot the issue. In this release, you can validate the JAXBContext instance at build time to detect and fix the JAXB errors by adding the property quarkus.jaxb.validate-jaxb-context=true.

Moreover, we have added the property quarkus.jaxb.exclude-classes to exclude classes to be bounded to the JAXBContext. This property accepts either a comma-separated list of fully qualified class names, for example:

quarkus.jaxb.exclude-classes=org.acme.one.Model,org.acme.two.Model

Or a list of packages, for example:

quarkus.jaxb.exclude-classes=org.acme.*

In this example, the classes org.acme.one.Model and org.acme.two.Model won’t be automatically bounded to the default JAXBContext instance.

Testing

Removal of @io.quarkus.test.junit.NativeImageTest and @io.quarkus.test.junit.DisabledOnNativeImageTest annotations

These annotations were marked as deprecated for removal since Quarkus 2.8.0.Final and they were finally removed.

Use @io.quarkus.test.junit.QuarkusIntegrationTest and @io.quarkus.test.junit.DisabledOnIntegrationTest respectively instead.

Keystore default password

Quarkus used "password" as the default password for JWT key and keystores. This default value has been removed. So, if you used "password," you now need to configure that password in the application.properties file:

quarkus.oidc-client.credentials.jwt.key-store-password=password
quarkus.oidc-client.credentials.jwt.key-password=password

Management interface

You can now expose the metrics and health endpoint on a separate HTTP server using quarkus.management.enabled=true. Note that for the endpoint exposed on that management interface, the paths are resolved differently:

  • the root path is configured using quarkus.management.root-path; quarkus.http.root-path is only used for the main HTTP server

  • the quarkus.http.non-application-root-path is not used for endpoints exposed on the management interface.

OpenTelemetry

OpenTelemetry (OTel) 1.23.1 introduced breaking changes. Some of them are: - HTTP span names are now "{http.method} {http.route}" instead of just "{http.route}". - All methods in all Getter classes in instrumentation-api-semconv have been renamed to use the get() naming scheme - Semantic conventions changes:

Deprecated attribute Property to use

messaging.destination_kind

messaging.destination.kind

messaging.destination

messaging.destination.name

messaging.consumer_id

messaging.consumer.id

messaging.kafka.consumer_group

messaging.kafka.consumer.group

The Full sets of changes can be checked here and here.

OpenTracing

  • OpenTracing support has been deprecated since Quarkus 2.14. We encourage moving to OpenTelemetry as soon as possible. The OpenTracing support will be removed soon.

Devtools

Maven versions

  • The lowest supported Maven version has changed from 3.6.2 to 3.6.3 following a refactoring of Quarkus Maven plugins migrating from the old Plexus component API to the JSR-330.

Removal of quarkus-bootstrap-maven-plugin Maven plugin

  • The io.quarkus:quarkus-bootstrap-maven-plugin Maven plugin has been deprecated since 2.10.0.Final and no longer exists. If your extension uses it, you must change the artifact ID to io.quarkus:quarkus-extension-maven-plugin. The update recipe should also perform this change (see here)

Current Version

Migration Guide 3.16

Next Version

Migration Guide 3.17

Clone this wiki locally