-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Migration Guide 3.9
- RESTEasy Reactive extensions renamed to Quarkus REST ⚙️ ✅
- SmallRye Reactive Messaging extensions renamed to Quarkus Messaging ⚙️ ✅
- Panache annotation processor removed for Hibernate ORM/Hibernate Reactive/MongoDB ⚙️ ✅
- Datasources
- OpenTelemetry
- RESTEasy Reactive: Adding web links programmatically
- RESTEasy Reactive: Filters on non REST paths
- Elasticsearch/OpenSearch
- Hibernate Search
- Update to Infinispan 15
- Keystore and trust store default format change
- JUnit Pioneer version not enforced anymore
- GraalVM SDK update ⚙️ ✅
quarkus-app
directory creation
Note
|
We highly recommend the use of Items marked below with ⚙️ ✅ are automatically handled by |
RESTEasy Reactive has been our default REST layer for a while and has always been supporting blocking workloads and the name was confusing.
Some users were not using it because they thought it wouldn’t work well for their usual blocking workloads. Some other users thought that when using RESTEasy Reactive, they had to use Hibernate Reactive, which is not true: you can use Hibernate ORM with Hibernate Reactive.
In Quarkus 3.9, we decided to rename RESTEasy Reactive to Quarkus REST.
While this change looks like a big change for you, we put Maven relocations in place and quarkus update
will automatically update your projects to the new artifacts.
We tried hard to be consistent across our stack:
-
Extensions named
-rest
are extensions using Quarkus REST (and RESTEasy Reactive) -
Extensions named
-resteasy
are extensions using RESTEasy Classic
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 changed:
Old config root | New config root |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
An automatic fallback mechanism has been put in place to fall back to the old configuration properties.
If you are an extension developer, you might also be impacted by these artifacts being 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 |
The SmallRye Reactive Messaging extensions have been renamed to quarkus-messaging-*
to convey the fact that they also support blocking workloads.
While this change looks like a big change for you, we put Maven relocations in place and quarkus update
will automatically update your projects to the new artifacts.
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 changed from quarkus.smallrye-reactive-messaging.
to quarkus.messaging.
.
An automatic fallback mechanism has been put in place to fall back to the old configuration properties.
If you are an extension developer, you might also be impacted by these artifacts being 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 |
For externally defined entities, in Hibernate ORM with Panache, Hibernate Reactive with Panache, and MongoDB with Panache, we used to require to run the io.quarkus:quarkus-panache-common
annotation processor, which would be automatic when found in the classpath, except in case you overrode the set of annotation processors to run in your build tool, in which case you had to add the annotation processor explicitly in your build tool.
With Quarkus 3.9, this is no longer required, and the annotation processor has been removed, so you should remove all usage of the io.quarkus:quarkus-panache-common
annotation processor from your build files.
For Maven builds, this would be located here:
<build>
<plugins>
[...]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.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>
[...]
</plugins>
</build>
For Gradle, this would be located here:
dependencies {
annotationProcessor "io.quarkus:quarkus-panache-common"
}
Starting with Quarkus 3.9, attempting to access multiple non-XA datasources in the same transaction would result in an exception similar to the one below, due to a significant risk of non-transactional behavior:
...
Caused by: java.sql.SQLException: Exception in association of connection to existing transaction
at io.agroal.narayana.NarayanaTransactionIntegration.associate(NarayanaTransactionIntegration.java:130)
...
Caused by: java.sql.SQLException: Failed to enlist. Check if a connection from another datasource is already enlisted to the same transaction
at io.agroal.narayana.NarayanaTransactionIntegration.associate(NarayanaTransactionIntegration.java:121)
...
For more information, recommendations, and ways to change this behavior, see this section of the documentation.
Current Semantic Conventions for HTTP will soon change and the current conventions are deprecated for removal soon.
Please move to the new conventions by setting the new property quarkus.otel.semconv-stability.opt-in
to http
for the new conventions or http/dup
to produce duplicated old and new conventions attributes.
Please check the OpenTelemetry extension configuration reference for more details and full set of changes at the HTTP semantic convention stability migration guide from OpenTelemetry.
The HAL wrappers class signatures have been updated to include the type of elements in the collection as listed below.
-
HalCollectionWrapper<T>
-
HalEntityWrapper<T>
You should add the type argument everywhere you use the HAL wrapper classes.
The preferred way of creating the wrapper classes changed from using the constructor to use helper methods exposed on the io.quarkus.hal.HalService
bean as shown below:
@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;
}
}
Creating the wrappers using the constructors will still work for now, but this might change in the future.
In the pre 3.9 versions, if you have a JAX-RS Filter, that filter will run, even in the case that the requested resource was not a REST resource. This will not happen anymore. Filters for JAX-RS will now only run on JAX-RS resources. In the case that you want your Filters to also run on non JAX-RS resource, you need to add your own ExceptionMapper:
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();
}
}
Now, JAX-RS becomes responsible for the Not Found resources, and the Filter will run. In the pre-3.9 version where this always happens, it makes it impossible for other extensions to handle Not Found.
The Elasticsearch/OpenSearch Dev Services now default to starting:
-
Elasticsearch 8.12, instead of 8.9 previously
-
OpenSearch 2.11, instead of 2.9 previously
To force the use of a specific distribution (Elasticsearch vs. OpenSearch) or version, configure the container image explicitly.
The Quarkus extension for Hibernate Search with outbox-polling relies on system tables in your database, and with Quarkus 3.9 the schema of these system tables may need to change.
See this section of the Hibernate Search migration guide for information on how to migrate your database schema if you were using that extension.
If you cannot update your database schema at the moment, you can use the following settings to restore previous defaults:
-
For the default persistence unit:
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:
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
Prior to Quarkus 3.9 and the Infinispan 15 integration, queries were executed by calling the following code: .Query.java
QueryFactory queryFactory = Search.getQueryFactory(booksCache); (1)
Query query = queryFactory.create("from book_sample.Book");
List<Book> list = query.execute().list();
-
Breaking change in 3.9
This code won’t work anymore since RemoteCache
is now an @ApplicationScoped
proxy bean.
Search.getQueryFactory
will raise a ClassCastException.
Remove the indirection by using the query
method in the RemoteCache
API as follows.
Query<Book> query = booksCache.<Book>query("from book_sample.Book");
List<Book> list = query.execute().list();
In 3.9, JKS is no longer the default keystore and trust store format. Quarkus makes an educated guess based on the file extension:
-
.pem
,.crt
and.key
are read as PEM certificates and keys -
.jks
,.keystore
and.truststore
are read as JKS key stores and trust stores -
.p12
,.pkcs12
and.pfx
are read as PKCS12 key stores and trust stores
If your file does not use one of these extensions, you need to set the format using:
quarkus.http.ssl.certificate.key-store-file-type=JKS # or P12 or PEM
quarkus.http.ssl.certificate.trust-store-file-type=JKS # or P12 or PEM
JKS is less and less used. Since Java 9, the default keystore format in Java is PKCS12. The most significant difference between JKS and PKCS12 is that JKS is a format specific to Java. At the same time, PKCS12 is a standardized and language-neutral way of storing encrypted private keys and certificates.
The org.junit-pioneer:junit-pioneer
dependency version is not enforced by the Quarkus BOM anymore. Make sure you define the version in your build files if you are using this dependency.
In Quarkus 3.8.3, we updated the GraalVM SDK artifacts version to 23.1.2. It was an oversight and should have been done long ago.
If you are developing extensions containing GraalVM substitutions,
it is highly recommended to replace the org.graalvm.sdk:graal-sdk
dependency with org.graalvm.sdk:nativeimage
,
that only contains the classes required to develop substitutions.
Also if you are using the Javascript polyglot features of GraalVM, org.graalvm.js:js
should be replaced by:
-
org.graalvm.polyglot:js-community
if you are using the community version of GraalVM -
org.graalvm.polyglot:js
if you are using the enterprise version of GraalVM
While the first change is handled by quarkus update
, the second one has to be done manually depending on your GraalVM distribution of choice.
Prior to Quarkus 3.9, the quarkus-app
directory was always created in the build system’s output directory, regardless of the type of artifact being produced.
This errorneous behavior has been fixed in Quarkus 3.9. Practically this which means that quarkus-app
will only be created when the artifact being produced is a fast-jar
(which is the default produced artifact if nothing has been configured).