diff --git a/migration/Migration-Guide-1.1.asciidoc b/migration/Migration-Guide-1.1.asciidoc new file mode 100644 index 0000000000..33da957f13 --- /dev/null +++ b/migration/Migration-Guide-1.1.asciidoc @@ -0,0 +1,95 @@ +## Hibernate Search + Elasticsearch (Preview) + +`quarkus.hibernate-search.elasticsearch.automatic-indexing.synchronization.strategy` has been renamed to `quarkus.hibernate-search.automatic-indexing.synchronization.strategy`. + +If you are using our Hibernate Search + Elasticsearch extension, there's a good chance you will need to adjust your configuration. + +## Neo4j (Preview) + +The Neo4j driver was updated to the Final 4.0 version and they have renamed a few classes, most notably `org.neo4j.driver.reactive.RxResult.RxStatementResult` has been renamed to `org.neo4j.driver.reactive.RxResult`. + +## Gradle plugin + +We now recommend using Gradle 6.0.1+. Starting from this version the Gradle plugin is no longer deployed in Maven Central, therefore some minor changes in your Gradle project might be needed. + +### Changes in the `settings.gradle` file + +Let's start by changing the `settings.gradle` file. It should be changed from (`rootProject.name` value may vary depending on your project name): + +```gradle +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + } + resolutionStrategy { + eachPlugin { + if (requested.id.id == 'io.quarkus') { + useModule("io.quarkus:quarkus-gradle-plugin:1.0.1.Final") + } + } + } +} + +rootProject.name='my-project' +``` +to: +```gradle +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + } + plugins { + id 'io.quarkus' version "${quarkusPluginVersion}" + } +} +rootProject.name='my-project' +``` + +NOTE: the `plugins{}` method is not supported in Gradle 5.x. In this case make sure to explicitly declare the plugin version in the `build.gradle` file. + +### Changes in the `build.gradle` file + +Change your `build.gradle` file to use the plugin DSL format, from: + +```gradle +// this block is necessary to make enforcedPlatform work for Quarkus plugin available +// only locally (snapshot) that is also importing the Quarkus BOM +buildscript { + repositories { + mavenLocal() + } + dependencies { + classpath "io.quarkus:quarkus-gradle-plugin:${quarkusPluginVersion}" + } +} + +plugins { + id 'java' +} + +apply plugin: 'io.quarkus' +``` +to: +```gradle +plugins { + id 'java' + id 'io.quarkus' +} + +``` + +## Extension framework + +### Updated configuration framework + +Our configuration framework got a big update to fix a number of issues all around. + +The main consequence of this change is that you will need to mark optional collections and maps as `Optional` in your config classes (that means `Optional>` for instance). + +### GizmoAdaptor + +The `GizmoAdaptor` class has been renamed to `GeneratedClassGizmoAdaptor`, due to the introduction of `GeneratedBeanGizmoAdaptor`. \ No newline at end of file diff --git a/migration/Migration-Guide-1.10.md b/migration/Migration-Guide-1.10.md new file mode 100644 index 0000000000..680b9f82c3 --- /dev/null +++ b/migration/Migration-Guide-1.10.md @@ -0,0 +1,14 @@ +## Hibernate ORM + +* `quarkus.hibernate-orm.log.bind-param` is deprecated and has been renamed `quarkus.hibernate-orm.log.bind-parameters`. The former will be removed at a later stage. + +## Hibernate Search ORM + Elasticsearch (Preview) + +* You should update your Maven/Gradle dependencies: replace any occurrence of the artifact ID `hibernate-search-elasticsearch` with `hibernate-search-orm-elasticsearch` +* You should update your configuration: replace any occurrence of the prefix `quarkus.hibernate-search.` with `quarkus.hibernate-search-orm. +* Many deprecated methods and classes were removed. For more information: https://in.relation.to/2020/11/04/hibernate-search-6-0-0-CR1/#breaking_changes +* Async/reactive methods now return `CompletionStage` instead of `CompletableFuture`. To convert a `CompletionStage` to a `Future`, call `.toCompletableFuture()`.` + +## MongoDB + +* The name of the default client is now `` instead of the previous `__default__` to be more consistent with the rest of the code base. It shouldn't have too many consequences but typically the health checks now expose the new name. \ No newline at end of file diff --git a/migration/Migration-Guide-1.11.md b/migration/Migration-Guide-1.11.md new file mode 100644 index 0000000000..0979e62f0e --- /dev/null +++ b/migration/Migration-Guide-1.11.md @@ -0,0 +1,55 @@ +## Log min-level + +If you are using TRACE (or DEBUG too if using 1.11.0.Final or 1.11.1.Final - changed in 1.11.2.Final) log level, we made an important change in our logging layer: a new build-time `min-level` configuration property was introduced that sets the minimum log level you will be able to use at runtime. + +So if you are logging at TRACE level for some loggers, setting `min-level` to TRACE is required. + +## Non-application endpoints moved to their own namespace + +[Path resolution for configurable endpoints](https://quarkus.io/blog/path-resolution-in-quarkus/) changed in this release. This transition was a little rough. There are some differences in behavior between 1.11.0.Final, when this was introduced, and 1.11.5.Final, when issues were resolved. + +By default, non-application endpoints, like health and metrics, are now grouped under `/q`. + +Convenience redirects from previous URLs to new namespaced URLs can be enabled and disabled by setting: +`quarkus.http.redirect-to-non-application-root-path=false` + +Disable the Quarkus non-application endpoints by setting the non-application endpoint root to be the same as the http root: +`quarkus.http.non-application-root-path=${quarkus.http.root-path}` + +You can customize the root used for non-application endpoints by setting `quarkus.http.non-application-root-path` to an alternative path. + +As of 1.11.5.Final, leading slashes in configured paths are significant. Please see [Path resolution in Quarkus](https://quarkus.io/blog/path-resolution-in-quarkus/) for more details and examples. + +## Jackson + +The default `ObjectMapper` obtained via CDI and consumed by the Quarkus extensions now ignores unknown properties (by disabling the `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` feature). + +See https://quarkus.io/guides/rest-json#jackson for more details about how to go back to the previous behavior. + +## Kubernetes Client + +We upgraded the Kubernetes Client to version 5. Please refer to the [Kubernetes Client migration guide](https://github.com/fabric8io/kubernetes-client/blob/master/doc/MIGRATION-v5.md) for more information. + +## Hibernate Search ORM + Elasticsearch + +* The default required status for Elasticsearch indexes is now `yellow`. If you have specific requirements and need to wait for indexes to be `green` on startup, set `quarkus.hibernate-search.elasticsearch.schema-management.required-status` to `green`. +* [Queries](https://docs.jboss.org/hibernate/search/6.0/reference/en-US/html_single/#troubleshooting-logging-query) +and [requests](https://docs.jboss.org/hibernate/search/6.0/reference/en-US/html_single/#troubleshooting-logging-elasticsearch-request) +are now logged at the `TRACE` level instead of the `DEBUG` level. + +## MongoDB Panache + +* A recent change was made to MongoDB panache to bring it in to conformity with the Hibernate Panache behavior. Public field accesses on `MongoEntity` and `ReactiveMongoEntity` types are now wrapped with the appropriate `get` or `set` methods. In general, you will like not see any difference in your application. However, if you have written a custom `get` or `set` method you may notice a change in behavior if those custom methods deviate from the standard `get`/`set` paradigm. See [this issue](https://github.com/quarkusio/quarkus-quickstarts/pull/726) for an example of something you might run in to. + +## quarkus-smallrye-jwt-build + +A new `quarkus-smallrye-jwt-build` extension has been introduced allowing users to generate JWT tokens without having to depend on `quarkus-smallrye-jwt` extension which is used for verifying JWT tokens. + +## GraalVM 20.3 + +We upgraded the base container image to build native executables to GraalVM 20.3. + +However, we hit a regression in the ImageIO support so if you are using ImageIO and seeing errors such as `UnsatisfiedLinkError: no awt in java.library.path`. This regression is specific to GraalVM 20.3.0 and will be fixed in GraalVM 20.3.1. Your options are: + +* Go back to GraalVM 20.2 until we upgrade to GraalVM 20.3.1: `quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-native-image:20.2.0-java11` +* Use [Mandrel](https://github.com/graalvm/mandrel/releases) in which we backported some additional ImageIO support from GraalVM master: `quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel:20.3-java11` \ No newline at end of file diff --git a/migration/Migration-Guide-1.12.md b/migration/Migration-Guide-1.12.md new file mode 100644 index 0000000000..697a33ddcc --- /dev/null +++ b/migration/Migration-Guide-1.12.md @@ -0,0 +1,127 @@ +## Fast-jar as default + +Fast-jar is a new Quarkus application packaging format that is faster to boot, compared to our legacy jar packaging. It was introduced several versions ago and it brings many improvements that made us make it the new default. + +### Starting the application + +The biggest change here is that to start your Quarkus application, you should now use: + +```bash +java -jar target/quarkus-app/quarkus-run.jar +``` + +(instead of using the versioned `-runner` jar) + +This change will concern all your applications as soon as you have upgraded them to 1.12. + +When deploying your application, make sure to deploy the entire `quarkus-app` directory. + +For those who want to stick to the legacy jar packaging, they can go back to the previous behavior by adding the following property to the `application.properties`: + +```properties +quarkus.package.type=legacy-jar +``` + +### Dockerfiles + +For existing applications, you have two Dockerfiles: + +- `Dockerfile.jvm`: this is the one for the `legacy-jar` packaging +- `Dockerfile.fast-jar`: this is the one for `fast-jar` packaging (so the new default) + +For newly generated applications, the situation is a bit different: + +- `Dockerfile.jvm`: this is the one for the `fast-jar` packaging (so the new default) +- `Dockerfile.legacy-jar`: this is the one for `legacy-jar` + +Note that if you want all your applications to be consistent, you can just update the Dockerfiles of your existing applications with the ones of a newly generated project. + +You can find an example of the new Fast jar Dockerfile [here](https://github.com/quarkusio/quarkus-quickstarts/blob/master/validation-quickstart/src/main/docker/Dockerfile.jvm). + +## Quarkus Maven Plugin + +We cleaned up a few things in the Quarkus Maven Plugin. Make sure the `quarkus-maven-plugin` section of the `pom.xml` of your project looks like: + +```xml + + io.quarkus + quarkus-maven-plugin + ${quarkus-plugin.version} + true + + + + build + generate-code + generate-code-tests + + + + +``` + +## Mutiny + +Mutiny has deprecated a few APIs. The deprecated APIs are still available and would work, but are planned for removal. + +Changed APIs are: + +* `multi.collectItems()` -> `multi.collect()` +* `multi.groupItems()` -> `multi.group()` +* `multi.transform().byTakingFirstItems(long)/byTestingItemsWith()/byFilteringItemsWith()` -> `multi.select().first(long)`, `multi.select().when(Function>)`, `multi.select().where(Predicate)` +* `multi.transform().toHotStream()` -> `multi.toHotStream()` +* `multi.transform().bySkippingFirstItems(long)` -> `multi.skip().first(long)` + +Mutiny removes two methods (deprecated for 11 months): + +* `uni.subscribeOn` -> `uni.runSubscriptionOn()` +* `multi.subscribeOn` -> `multi.runSubscriptionOn()` + + +## Mailer + +* The `MailTemplateInstance` now returns a `Uni` instead of `CompletionStage`. To convert a `Uni` to a `CompletionStage`, call `.subscribeAsCompletionStage()`. + +## Vert.x + +* The Axle and RX Java API from Vert.x are no more exposed, use the Mutiny API instead. These features were deprecated since February 2020. + +## HTTP + +A couple of the default file upload settings have changed. + +`quarkus.http.body.delete-uploaded-files-on-end` now defaults to `true` (the reason being that no uploaded files should be left over on the server by default). +`quarkus.http.body.uploads-directory` now defaults to `${java.io.tmpdir}/uploads` (the reason being that some application might not have the permissions to write to the current working directory) + + +[Path resolution for configurable endpoints](https://quarkus.io/blog/path-resolution-in-quarkus/) changed in this release. + +By default, non-application endpoints, like health and metrics, are now grouped under `/q`. + +Convenience redirects from previous URLs to new namespaced URLs can be enabled and disabled by setting: +`quarkus.http.redirect-to-non-application-root-path=false` + +Disable the Quarkus non-application endpoints by setting the non-application endpoint root to be the same as the http root: +`quarkus.http.non-application-root-path=${quarkus.http.root-path}` + +You can customize the root used for non-application endpoints by setting `quarkus.http.non-application-root-path` to an alternative path. + +As of 1.12.1.Final, leading slashes in configured paths are significant. Please see [Path resolution in Quarkus](https://quarkus.io/blog/path-resolution-in-quarkus/) for more details and examples. + +## Rest Client Exceptions + +If you are using `quarkus-rest-client` then please be aware that MP REST Client or JAX-RS Client invocation exceptions will no longer have JAX-RS `Response` available by default to avoid leaking some potentially sensitive downstream endpoint data such as cookies. You can set `resteasy.original.webapplicationexception.behavior=true` in `application.properties` if you need to access the exception `Response`. +Please see https://docs.jboss.org/resteasy/docs/4.5.9.Final/userguide/html/ExceptionHandling.html#ResteasyWebApplicationException for more information. + +## Version of distroless image + +If you are using the distroless image, please note that it now has an immutable version so you might have to update your Dockerfiles to use: `quay.io/quarkus/quarkus-distroless-image:1.0` instead of `quay.io/quarkus/quarkus-distroless-image:20.3-java11`. + + +## Kafka Health Check + +Readiness health checks for _incoming_ Kafka channel may report _DOWN_ if they are consumed lazily (like using SSE). To avoid this, disable the readiness health check: + +``` +mp.messaging.incoming.your-topic.health-readiness-enabled=false +``` \ No newline at end of file diff --git a/migration/Migration-Guide-1.13.md b/migration/Migration-Guide-1.13.md new file mode 100644 index 0000000000..c56234e3d9 --- /dev/null +++ b/migration/Migration-Guide-1.13.md @@ -0,0 +1,48 @@ +## Configuration + +All `application.properties` files found in the classpath are loaded in the Quarkus configuration. Files in the current application will have priority and files in dependencies will use the classloader order. This means, that your Quarkus application may pick up additional configuration that was not picked up previously and possible change the behaviour of your application. + +## Jackson + +`SerializationFeature.WRITE_DATES_AS_TIMESTAMPS` is now **disabled** by default which means your temporal types will be serialized as strings (e.g. `1988-11-17T00:00:00Z`) starting 1.13, instead of numeric values. + +You can easily go back to the previous behavior by adding `quarkus.jackson.write-dates-as-timestamps=true` to your `application.properties`. + +## Live Reload Instrumentation + +`quarkus.dev.instrumentation` has been renamed to `quarkus.live-reload.instrumentation` to be more consistent with other configuration properties related to live reload. + +## Removal of the `native-image` Maven goal + +The goal `native-image` of `quarkus-maven-plugin` had long been deprecated and the plugin had been logging a warning since `1.11.1.Final`. + +It has now finally been removed in 1.13. Please remove the plugin execution from your `pom.xml` and simply add the following property to your native profile: + +```xml + + native + +``` + +In case you have been setting non-default configuration parameters like `true`, replace those with the respective [documented properties](https://quarkus.io/guides/building-native-image#configuration-reference), e.g. `true`. + +## Removal of the Maven `uberJar` and Gradle `--uber-jar` parameters + +Both the Maven `uberJar` and the Gradle `--uber-jar` parameters had been deprecated since `1.11.2.Final`/`1.12.0.CR1` and have now been removed in 1.13. + +As a replacement, add `quarkus.package.type=uber-jar` to your `application.properties` (or e.g. `pom.xml`). + +## New methods signatures in `AuthenticationRequest` + +New methods signatures have been added to the `AuthenticationRequest` interface to allow transportation of additional context information with the request such as context path, HTTP header or query parameter values. If you were implementing this interface before, you can now extend `BaseAuthenticationRequest` in 1.13 without having to implement the new methods. + +## Kafka + +Kafka `group.id` now defaults to application name (as configured by `quarkus.application.name`). +Only if the application name isn't set, a random string is used. + +Automatic generation of a random string is merely a development convenience. +You shouldn't rely on it in production. + +If you require application instances to have a unique Kafka `group.id`, you should ensure that explicitly. +For example, you can set the `KAFKA_GROUP_ID` environment variable. \ No newline at end of file diff --git a/migration/Migration-Guide-1.2.md b/migration/Migration-Guide-1.2.md new file mode 100644 index 0000000000..d3ad7ee095 --- /dev/null +++ b/migration/Migration-Guide-1.2.md @@ -0,0 +1,74 @@ +## Hibernate ORM + +In Quarkus, the bytecode enhancement of Hibernate ORM is always on. +We used to enable the automatic association management but there are cases where it doesn't work well. + +It is now disabled. You have to manage both sides of an association manually from now on (as with a classic configuration of Hibernate ORM). + +## MongoDB + +We switched from `mongo-java-driver` to `mongodb-driver-sync` which means that the legacy `com.mongodb.MongoClient` is not there anymore and should be replaced by `com.mongodb.client.MongoClient`. + +## Native images and GraalVM + +You can either use: + + * GraalVM 19.2.1 + * or GraalVM 19.3.1 with JDK 8 or JDK 11 + +GraalVM 19.3.0.x is not supported anymore. + +## Hibernate Search + Elasticsearch (Preview) + +The protocol used to contact Elasticsearch is now specified in a separate configuration property, `quarkus.hibernate-search.elasticsearch.protocol`. This property defaults to `http`. + +As a result, the property `quarkus.hibernate-search.elasticsearch.discovery.default_scheme` was removed. + +So if your configuration looked like this: +``` +quarkus.hibernate-search.elasticsearch.hosts = http://es1.mycompany.com +``` + +You should now have this: +``` +quarkus.hibernate-search.elasticsearch.hosts = es1.mycompany.com +``` + +And if it looked like this: +``` +quarkus.hibernate-search.elasticsearch.hosts = https://es1.mycompany.com +quarkus.hibernate-search.elasticsearch.discovery.enabled = true +quarkus.hibernate-search.elasticsearch.discovery.default_scheme = https +``` + +You should now have this: +``` +quarkus.hibernate-search.elasticsearch.hosts = es1.mycompany.com +quarkus.hibernate-search.elasticsearch.protocol = https +quarkus.hibernate-search.elasticsearch.discovery.enabled = true +``` + +## @ConfigProperties + +In previous versions of Quarkus, `@ConfigProperties` made the assumption that the name of the class fields (or method names when talking about interfaces) would exactly match to the property name. +For example: + +``` +@ConfigProperties +public class SomeConfig { + public String fooBar; +} +``` + +meant that setting `fooBar` would require the `some.fooBar` property. + +This behavior is unintuitive however, so we have changed it to use kebab-case properties instead, which means that you now need to set the `some.foo-bar` property. + +If keeping the old behavior is desired, there are two options: + +* Set `@ConfigProperties(namingStrategy=NamingStrategy.VERBATIM)` for each class that uses `ConfigProperties` and for which the old behavior is desired +* Set the `quarkus.arc.config-properties-default-naming-strategy=verbatim` property. This makes the old behavior the default for `@ConfigProperties` classes. + +## Test framework + +The `quarkus-vault-test` artifact has been renamed to `quarkus-test-vault` to be more consistent with our other test framework artifacts. \ No newline at end of file diff --git a/migration/Migration-Guide-1.3.md b/migration/Migration-Guide-1.3.md new file mode 100644 index 0000000000..cfc8d6ff49 --- /dev/null +++ b/migration/Migration-Guide-1.3.md @@ -0,0 +1,194 @@ +## Maven + +You need to upgrade Maven to 3.6.2+ due to a bug in Maven resolver. + +## JUnit + +You need JUnit 5.6+. It's included in our BOM but if you specify the version manually, you need to upgrade. + +## REST Assured + +REST Assured was updated to 4.2. + +If you are tuning the Jackson `ObjectMapper`, you need to change: +```java +RestAssured.objectMapper(objectMapper); +``` +to: +```java +RestAssured.config().getObjectMapperConfig().defaultObjectMapper(objectMapper); +``` +as they removed the shortcut. + +## Class Loading + +The class loading model for dev and test mode has changed, which should fix a number of issues around class loading that have been reported. Most applications should continue to work as normal with no changes required, however there are some changes that may effect testing. The most visible change is that `@BeforeAll` methods are now always run after Quarkus has started, so they can't be used to start resources Quarkus needs before boot. If you need to start resources before Quarkus has booted you can use the `@QuarkusTestResource` annotation to specify a `QuarkusTestResourceLifecycleManager` that can start and stop the resources. + +## Native images and GraalVM + +19.3.1 and 20.0.0 are supported. Older versions are not. + +Both JDK 8 and JDK 11 should work but keep in mind that GraalVM JDK 11 is a tech preview. + +## Hibernate Validator + +If you use Hibernate Validator in a multi-module project with constrained beans being in a library module, you need to be sure this library module is included in the bean archive index by adding a `src/main/resources/META-INF/beans.xml` empty file. + +Otherwise your constraints will be ignored. + +## Hibernate ORM and Hibernate ORM with Panache + +Bytecode-enhanced bi-directional association management is no longer activated. +It was not comprehensive and we decided to embrace the principle of least surprise and disable it. +Make sure to update both sides of your relationships explicitly in your code. + +[Some info about Bytecode-enhanced bi-directional association management](https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#BytecodeEnhancement-dirty-tracking-bidirectional) + +## Reactive Messaging + +The `Emitter` interface has slightly changed. First, the interface has moved to `org.eclipse.microprofile.reactive.messaging.Emitter`, as the interface is now part of the Reactive Messaging specification. + +Also, sending `Message` has changed. The Emitter generic parameter is the payload type and cannot be the `Message` type: + +``` +// Before +@Inject @Channel("channel") Emitter> emitter; + +// Now +@Inject @Channel("channel") Emitter emitter; +emitter.send("foo"); +emitter.send(Message.of("foo")); +``` + +Sending a payload returns a `CompletionStage` completed when the message is acknowledged. + +## Reactive Messaging Kafka Message -> Record + +The `KafkaMessage` class has been renamed into `KafkaRecord` to be closer to the Kafka lingo. + +The `@Stream` annotation has been replaced by the `@Channel` annotation. + +## Mutiny + +In 1.3, a new reactive programming API has been introduced. This API named Mutiny (https://smallrye.io/smallrye-mutiny/) replaces the Axle and Reactive Streams Operators models (Reactive Streams and Completion Stage). The previous models are still functional, but deprecated and will be removed in the future. Refer to the various guides to show the differences and use the new API. + +## Hibernate Search + Elasticsearch (Preview) + +### Search DSL + +A few methods in the Search DSL have been renamed: + +* `searchSession.search(...).predicate(...)` becomes `searchSession.search(...).where(...)`. +* `searchSession.search(...).asProjection(...)` becomes `searchSession.search(...).select(...)`. +* `searchSession.search(...).asProjections(...)` becomes `searchSession.search(...).select(...)`. +* `searchSession.search(...).asEntity(...)` becomes `searchSession.search(...).selectEntity()`. +* `searchSession.search(...).asEntityReference(...)` becomes `searchSession.search(...).selectEntityReference()`. + +The methods with the old name are still present, though deprecated. +They will be removed before Hibernate Search 6.0.0.Final is released. + +### Index layout + +Elasticsearch indexes are now accessed through aliases only. +Hibernate Search relies on two aliases for each index: one for writes (`-write`) and one for reads (`-read`). + +As a result, you will need to either create the two aliases, +or drop your indexes and have Hibernate Search re-create empty indexes on startup: it will create the aliases. + +See [this section of the reference documentation](https://docs.jboss.org/hibernate/search/6.0/reference/en-US/html_single/#backend-elasticsearch-indexlayout) +for more information about index layout. + +### Configuration + +The names of synchronization strategies for automatic indexing have changed: + +* `queued` => `async`. +* `committed` (the default) => `write-sync` (still the default). +* `searchable` (commonly used for tests) => `sync` (still recommended for tests only). + +So if your configuration looked like this: + +``` +quarkus.hibernate-search.automatic_indexing.synchronization.strategy = queued +``` + +You should now have this: + +``` +quarkus.hibernate-search.automatic_indexing.synchronization.strategy = async +``` + +And if it looked like this: + +``` +quarkus.hibernate-search.automatic_indexing.synchronization.strategy = searchable +``` + +You should now have this: + +``` +quarkus.hibernate-search.automatic_indexing.synchronization.strategy = sync +``` + +See [this section of the reference documentation](https://docs.jboss.org/hibernate/search/6.0/reference/en-US/html_single/#mapper-orm-indexing-automatic-synchronization) for more information about synchronization strategies. + +## Kubernetes + +In 1.3, the configuration properties of the Kubernetes extension have changed in the following ways: + +* They are now prefixed with `quarkus.` +* Nested property arrays have been converted to maps. + + +For example the old property `kubernetes.replicas` is now +`quarkus.kubernetes.replicas`. This applies to all properties starting with +`kubernetes`, `openshift` and `knative`. For compatibility reasons the old properties will still work but the new ones will always take precedence. + +The other change affects properties that contained nested arrays, +like `env-vars` and `labels`: + +For example, labels used to be configured like: + +``` +kubernetes.labels[0].name=foo +kubernetes.labels[0].value=bar +``` + +But the new properties are configured like: + +``` +quarkus.kubernetes.labels.foo=bar +``` + +The same applies to complex objects too: + +``` +kubernetes.env-vars[0].name=FOO_ +kubernetes.env-vars[0].value=BAR + +kubernetes.env-vars[0].name=FOO2 +kubernetes.env-vars[0].secret=bar-secret + +kubernetes.env-vars[0].name=FOO3 +kubernetes.env-vars[0].config-map=bar-cfg +``` + +They can now be configured: + +``` +quarkus.kubernetes.env-vars.foo=value +quarkus.kubernetes.env-vars.foo2.secret=bar-secret +quarkus.kubernetes.env-vars.foo3.config-map=bar-cfg +``` + +## Deprecated classes removed + +The following unused and long-time deprecated classes were deleted from the codebase: + +* `io.quarkus.test.junit.SubstrateTest`(Replaced with `io.quarkus.test.junit.NativeImageTest`) +* `io.quarkus.test.junit.DisabledOnSubstrate` (Replaced with `io.quarkus.test.junit.DisabledOnNativeImage`) +* `io.quarkus.test.junit.DisabledOnSubstrateCondition` (Replaced with `io.quarkus.test.junit.DisabledOnNativeImageCondition`) +* `io.quarkus.infinispan.client.runtime.Remote` +* All classes in package `io.quarkus.deployment.builditem.substrate` (Replaced with `io.quarkus.deployment.builditem.nativeimage`) + +More information: https://github.com/quarkusio/quarkus/pull/5596 \ No newline at end of file diff --git a/migration/Migration-Guide-1.4.md b/migration/Migration-Guide-1.4.md new file mode 100644 index 0000000000..6e1e5ae882 --- /dev/null +++ b/migration/Migration-Guide-1.4.md @@ -0,0 +1,72 @@ +## Multi-module projects + +If your projects have multiple modules, for a number of extensions (Hibernate Validator for instance), we are not considering the combined index anymore (i.e. the one built of all the Jandex indexes present in your modules) but the bean archives index. + +This change allows us to consider generated classes for these extensions. + +What that means for you is that instead of generating a Jandex index via the Maven plugin in your secondary modules, add an empty `src/main/resources/META-INF/beans.xml`. This will make your classes part of the bean archives index and considered again by these extensions. + +## MongoDB + +We upgraded to the MongoDB client version 4. + +## Gradle plugin + +### JVM Arguments parameter is now a List + +If you are specifying extra JVM arguments in `quarkusDev` task, you need to change from: + +```gradle +tasks.withType(QuarkusDev) { + jvmArgs = "-Djavax.net.ssl.keyStore=/path/to/keystores/keystore.jks -Djavax.net.ssl.keyStorePassword=password" +} +``` + +to: +```gradle +tasks.withType(QuarkusDev) { + jvmArgs = ["-Djavax.net.ssl.keyStore=/path/to/keystores/keystore.jks", "-Djavax.net.ssl.keyStorePassword=password"] +} +``` + +### Task `buildNative` is now deprecated + +We have deprecated the `./gradlew buildNative` task in favor of `./gradlew build -Dquarkus.package.type=native`. If your build still uses `buildNative` you should see the following warning message: + +``` +The 'buildNative' task has been deprecated in favor of 'build -Dquarkus.package.type=native' +``` + +## Kogito + +The Kogito extension has been moved out of the Core repository: it is now part of the Quarkus Platform. + +The GA has changed so you should use `org.kie.kogito:kogito-quarkus` instead of `io.quarkus:quarkus-kogito`. + +## Hibernate Search + Elasticsearch (Preview) + +Configuration properties relative to Elasticsearch index lifecycle management have changed. +See [this section of the reference documentation](https://docs.jboss.org/hibernate/search/6.0/reference/en-US/html_single/#mapper-orm-schema-management) +for detailed documentation about schema management. + +In short: + +* `quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.strategy` +is now `quarkus.hibernate-search.index-defaults.schema-management.strategy` +and accepts the same values as before: `none`, `create`, `validate`, `update`, ... +* A new schema management strategy on startup was introduced: `create-or-validate`. +It create indexes if they don't exist, validates their schema if they already exist. +* The default schema management strategy on startup is now `create-or-validate`. +* `quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.required-status` +is now `quarkus.hibernate-search.elasticsearch.index-defaults.schema-management.required-status`. +* `quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.required-status-wait-timeout` +is now `quarkus.hibernate-search.elasticsearch.index-defaults.schema-management.required-status-wait-timeout`. + +Also related: you can now use [`SearchSchemaManager` APIs](https://docs.jboss.org/hibernate/search/6.0/reference/en-US/html_single/#mapper-orm-schema-management-manager) +to trigger schema management operations at the time of your choosing (not just on startup). + +## OIDC + +### OidcTenantConfig package change + +`OidcTenantConfig` has been moved from the `io.quarkus.oidc.runtime` package to `io.quarkus.oidc` package because `OidcTenantConfig` is used by `io.quarkus.oidc.TenantConfigResolver`. \ No newline at end of file diff --git a/migration/Migration-Guide-1.5.md b/migration/Migration-Guide-1.5.md new file mode 100644 index 0000000000..8725fd22cc --- /dev/null +++ b/migration/Migration-Guide-1.5.md @@ -0,0 +1,14 @@ +## Qute + +`io.quarkus.qute.api.VariantTemplate` was removed from the API. The functionality is now provided by an injected `io.quarkus.qute.Template`. Injected templates do not support the `getExpressions()`, `getGeneratedId()` and `getVariant()` methods. + +## Hibernate Search + Elasticsearch (Preview) + +`ElasticsearchSearchQuery#explain(String, String)` now expects the name of the mapped type to be passed as the first argument, instead of the index name. + +## Testcontainers + +The `org.testcontainers` artifacts are no longer in our BOM. +We still use them under the hood but we don't want to enforce the version of this test dependency on our users. + +The main consequence of this change is that you will have to define the Testcontainers artifacts versions in your projects. \ No newline at end of file diff --git a/migration/Migration-Guide-1.6.md b/migration/Migration-Guide-1.6.md new file mode 100644 index 0000000000..768cfdba1d --- /dev/null +++ b/migration/Migration-Guide-1.6.md @@ -0,0 +1,29 @@ +## Maximum size allowed for request body limited to 10 MB + +The maximum size allowed for the request body used to be unlimited by default, it's now limited to a safer default value of 10 MB. + +You can go back to the previous unlimited behavior by explicitly adding `quarkus.http.limits.max-body-size=` to your `application.properties`. + +## Hibernate ORM + +The charset for DDL generation and SQL import files is now UTF-8 by default instead of being the system charset. + +You can override it by adding `quarkus.hibernate-orm.database.charset=` to your `application.properties`. + +## OptaPlanner + +The OptaPlanner Quarkus extensions have been moved to the OptaPlanner project and are now part of the Quarkus Platform. + +The new GA are: + + * `org.optaplanner:optaplanner-quarkus` + * `org.optaplanner:optaplanner-quarkus-jackson` + * `org.optaplanner:optaplanner-quarkus-jsonb` + +The versions are included in the Platform BOM. + +## Native image and trustStore + +The trustStore handling for native images was broken in previous versions since the migration to GraalVM 19.3. + +It has been fixed. Be careful that the trustStore will be included in the native image at compilation time. \ No newline at end of file diff --git a/migration/Migration-Guide-1.7.md b/migration/Migration-Guide-1.7.md new file mode 100644 index 0000000000..fdca544143 --- /dev/null +++ b/migration/Migration-Guide-1.7.md @@ -0,0 +1,31 @@ +## Infinispan Embedded + +The Infinispan Embedded extension has been discontinued with no replacement. + +## Native executables + +### file.encoding set to UTF-8 + +Native executables use the `file.encoding` defined at build time. It used to be set to the locale of the build host. It is now hardcoded to UTF-8 at build time to avoid inconsistent behaviors. + +It is not configurable right now but if you have a use case for being able to configure it, please speak up on the `quarkus-dev` mailing list. + +### GraalVM 19.3 not supported anymore + +Starting with 1.7, we only support the JDK 11 flavor of GraalVM 20.1 for native executables building. + +## io.quarkus:quarkus-bom-deployment has been removed + +`io.quarkus:quarkus-bom-deployment` artifact was deprecated in 1.6.0.Final and now was removed completely in 1.7.0.Final. Its content (the deployment or build time Quarkus extension dependencies) was merged into `io.quarkus:quarkus-bom` artifact. Starting from 1.7.0.Final release, imports of `io.quarkus:quarkus-bom-deployment` should be changed to import `io.quarkus:quarkus-bom` instead. + +### S2I image + +The default S2I image is now a Java 11 image based on UBI: `registry.access.redhat.com/ubi8/openjdk-11`. + +## SmallRye Reactive messaging extension health checks are enabled by default + +SmallRye Reactive messaging extensions (eg. `io.quarkus:quarkus-smallrye-reactive-messaging-kafka`) automatically registers a Health Check for their respective messaging server (when `io.quarkus:quarkus-smallrye-health` is present). To disable this behavior, simply add the following to your `application.properties`: + +```properties +quarkus.reactive-messaging.health.enabled=false +``` \ No newline at end of file diff --git a/migration/Migration-Guide-1.8.md b/migration/Migration-Guide-1.8.md new file mode 100644 index 0000000000..4c642250ae --- /dev/null +++ b/migration/Migration-Guide-1.8.md @@ -0,0 +1,34 @@ +## Datasource configuration + +This is the last call to migrate your deprecated datasource configuration to the new one before it gets removed in Quarkus 1.9 - the new datasource configuration was introduced in Quarkus 1.3. + +So if you are still using `quarkus.datasource.url` or `quarkus.datasource.driver`, please refer to [the datasource guide](https://quarkus.io/guides/datasource) to migrate your configuration. + +## Hibernate ORM + +If you are using a `persistence.xml` to define your persistence units and want to enable entity class scanning, you need to add: +``` + +``` +to your `persistence.xml`. + +## Quartz + +The configuration for Quartz extension points (job listeners, trigger listeners, plugins) has changed. + +If you are using this advanced feature, please refer to the [updated Quarz configuration reference](https://quarkus.io/guides/quartz#quartz-configuration-reference) to migrate your existing configuration. + +## Hibernate Search + Elasticsearch (Preview) + +* Configuration properties for index defaults can no longer include the `.index-defaults` component. For example, `quarkus.hibernate-search.elasticsearch.index-defaults.schema-management.required-status` should now be written simply as `quarkus.hibernate-search.elasticsearch.schema-management.required-status`. +* `query.explain()` now expects to be passed an entity ID instead of a document ID. In short, if your entity has an ID of type `Long`, you need to pass a `Long` (previously you had to pass a `String`). +* `@IndexedEmbedded.storage`/`ObjectFieldStorage` have been renamed to `@IndexedEmbedded.structure`/`ObjectStructure`. The older syntax is deprecated and will eventually be removed. +* `quarkus.hibernate-search.elasticsearch.default-backend` no longer exists. You can either configure a default backend (`quarkus.hibernate-search.elasticsearch.someProperty someValue`) or named backends (`quarkus.hibernate-search.elasticsearch.backends."backend-name".someProperty someValue`), but a named backend can no longer be considered as the default backend. + +## Kubernetes Config + +* When setting `quarkus.kubernetes-config.secrets.enabled=true`, it is now no longer necessary to also set `quarkus.kubernetes-config.enabled=true` in order to read Secrets. + +## Jib + +* The quarkus-container-image-jib extension no longer sets the `quarkus.http.host` System Property to `0.0.0.0` because Quarkus defaults to `0.0.0.0` (which has been the case for a very long time). This change means that if `quarkus.http.host` is set in `application.properties`, then the container image created by Jib **will** honor the value - as opposed the previous behavior, which was that value being overriden by the `quarkus.http.host` System Property. diff --git a/migration/Migration-Guide-1.9.md b/migration/Migration-Guide-1.9.md new file mode 100644 index 0000000000..a6062acbe2 --- /dev/null +++ b/migration/Migration-Guide-1.9.md @@ -0,0 +1,42 @@ +## Datasource Configuration + +In 1.3, we introduced a new much more flexible datasource configuration supporting both JDBC and reactive datasources in a unified way. + +Until 1.9, we still supported the deprecated configuration properties but this leads to some confusion for the users mixing both old and new configuration properties. + +In 1.9, the deprecated configuration properties are gone so you need to move to the new ones: https://quarkus.io/guides/datasource . + +Quarkus will warn you about any use of the old deprecated configuration properties. + +## Redis Client Configuration + +The following configuration properties have been deprecated: +- `quarkus.redis.ssl`, +- `quarkus.redis.database`, +- `quarkus.redis.password` + +And they are all configurable via the `quarkus.redis.hosts` property using a connection string in the following format: +`redis://[username:password@][host][:port][/database]`. + +## Spring Boot @ConfigProperties + +The verbatim naming strategy previously used with Spring Boot properties extension is now replaced by the one defined in quarkus.arc.config-properties-default-naming-strategy property (with `kebab` being the default). + +To keep your application operating as before, perform one of the following changes: + +* Set `quarkus.arc.config-properties-default-naming-strategy=verbatim` in the `application.(yml|properties)` +* Or replace the properties from verbatim style to kebab (default) or the one defined in quarkus.arc.config-properties-default-naming-strategy property. + +## Reactive Messaging - Kafka + +* Kafka auto-commit is now disabled by default - you can re-enabled it using: `mp.messaging.incoming.my-channel.enable.auto.commit=true`. Enabling auto-commit sets the commit-strategy to _ignore_ (auto-commit will do the work, not the connector) +* The default commit-strategy is `latest` - you may want to switch to `throttled` to improve the consumption rate. Set it with: `mp.messaging.incoming.my-channel.commit-strategy=throttled` + +## Mutiny logging about dropped exceptions + +You may start seeing logs with: +``` +2020-10-30 17:33:39,400 ERROR [io.qua.mut.run.MutinyInfrastructure] (vert.x-eventloop-thread-X) Mutiny had to drop the following exception: .... +``` + +This log happens when Mutiny receives a failure but cannot dispatch it to a downstream subscriber as it would violate the Reactive Streams protocol. Before Quarkus 1.9, these exceptions were swallowed. \ No newline at end of file diff --git a/migration/Migration-Guide-2.0.md b/migration/Migration-Guide-2.0.md new file mode 100644 index 0000000000..1fbfc4736e --- /dev/null +++ b/migration/Migration-Guide-2.0.md @@ -0,0 +1,187 @@ +## JDK 11 + +The minimal JDK version supported by Quarkus 2.0 is JDK 11. + +JDK 8 is not supported anymore. + +## Maven 3.8 + +Maven 3.8.1 is the new minimum Maven version. +It fixes [an important CVE](https://maven.apache.org/docs/3.8.1/release-notes.html) so, in any case, it is highly recommended to upgrade to it. + +## Jandex upgrade + +We fixed some issues related to the Jandex indexer. +Jandex itself is part of our BOM so will be upgraded automatically but if you use some Jandex build plugins, you need to upgrade them yourself. + +* If you are using the Jandex Maven plugin, please upgrade it to 1.1.0. +* If you are using the Jandex Gradle plugin (`org.kordamp.gradle.jandex`), please upgrade it to 0.11.0. + +## SmallRye Config +Quarkus `@ConfigProperties` has been deprecated in favour of SmallRye Config `@ConfigMapping`. Please, refer to the [Mapping Configuration to Objects](https://quarkus.io/version/main/guides/config-mappings). + +## Mapping of YAML Configuration to complex objects + +Mapping of YAML Configuration to complex objects has been removed from `io.quarkus.arc.config.ConfigProperties`. Please use `io.smallrye.config.ConfigMapping` instead which is a safer alternative. + +## SmallRye JWT + +`smallrye.jwt.sign.key-location` has been renamed to `smallrye.jwt.sign.key.location` and `smallrye.jwt.encrypt.key-location` - to `smallrye.jwt.encrypt.key.location`. + +## Avro +Avro has been integrated with the Quarkus code generation mechanism. To use it with Maven, make sure you have the `generate-code` +goal enabled for the `quarkus-maven-plugin`, it should be enabled by default if you created your project fairly recently. +For Gradle no specific task is required. + +This replaces the need to use Avro plugin, such as the `avro-maven-plugin`, for projects that use Avro. + +## Apicurio Registry + Avro +A new extension for Apicurio Registry 2.x client libraries for Avro is present: `quarkus-apicurio-registry-avro`. +If you use Apicurio Registry 2.x client libraries for Avro (`io.apicurio:apicurio-registry-serdes-avro-serde`), you have to use this extension now (otherwise application build will fail). + +Support for Apicurio Registry 1.x client libraries for Avro, as well as Confluent Schema Registry libraries for Avro, is not affected. + +## Kubernetes / Openshift + +### VCS annotations + +The value `app.quarkus.io/vcs-url` is no longer converted to an `http` url and will now match the url of the `origin` remote. Users that need the prefer the use of the `http` protocol over `git`, will have to configure that on git level. + +### Service port mapping + +Services that are exposing http ports are now automatically mapped to port `80`. The change makes the generated `Service` easier to consume by external tools, or services as knowledge of the actual container port is no longer needed by consumers. +This may affect services that were using the service dns name and container port combination to communicate with each other. + +## Kubernetes Client + +The Kubernetes Client has been upgraded to 5.4, which contains some breaking changes. + +Please refer to [the release notes](https://github.com/fabric8io/kubernetes-client/releases/tag/v5.4.0) for more details. + +## gRPC + +The `io.quarkus.grpc.runtime.annotations.GrpcService` annotation was renamed to `io.quarkus.grpc.GrpcClient`. Furthermore, the `@GrpcClient.value()` is optional and the service name can be derived from the annotated element. + +gRPC service classes now have to be annotated with `@io.quarkus.grpc.GrpcService` instead of `@javax.inject.Singleton`. + +## Qute + +The deprecated annotations from the `io.quarkus.qute.api` package were removed. All occurrences of `@io.quarkus.qute.api.CheckedTemplate` should be replaced with `@io.quarkus.qute.CheckedTemplate` and occurrences of `@io.quarkus.qute.api.ResourcePath` should be replaced with `@io.quarkus.qute.Location`. + +Checked templates require type-safe expressions by default, i.e. expressions that can be validated at build time. It's possible to use `@CheckedTemplate(requireTypeSafeExpressions = false)` to relax this requirement. + +Multiple ``NamespaceResolver`` instances can be registered for the same namespace provided that each declares a different priority. + +## Quartz + +The deprecated property `quarkus.quartz.force-start` was removed. Use `quarkus.quartz.start-mode=forced` instead. + +The deprecated config value `StoreType.DB` was removed. `quarkus.quartz.store-type=db` should be replaced with `quarkus.quartz.store-type=jdbc-cmt`. + +## Keycloak Authorization + +Anonymous requests to public resources with no matching Keycloak Authorization policies will now correctly return HTTP `200` status as opposed to `401`. Adding `DISABLED` Keycloak Authorization policies in such cases is no longer necessary. + +In 2.0, we removed some features that were deprecated for a while. + +## Legacy Redirect for non-application endpoints such as `/health` + +When we introduced the new `/q` mounting point for `/health`, `/metrics`, and other non-application endpoints, +the `quarkus.http.redirect-to-non-application-root-path` configuration property was provided to revert back to the previous behavior of not prefixing them with `/q`. + +The property was deprecated and is now removed. + +It is possible to achieve the previous behavior by explicitly setting endpoints to be absolute instead of relative. For instance, the Health endpoint can be forced to be available at `/health` instead of `/q/health` by setting `quarkus.smallrye-health.root-path=/health`. + +### Impact on other services + +Services using non-application endpoints, such as Prometheus ServiceMonitor, should be adjusted accordingly. + +#### Prometheus ServiceMonitor + +In order to collect statistics for your service, the service monitor YAML file should declare `path: /q/metrics` under +the `endpoints` declaration. + +## Container Image JIB + +As of Quarkus 2.0, when the `quarkus.container-image.username` and `quarkus.container-image.password` properties are set, credentials from other locations (like the docker config on the file system) will be ignored + +## Databases + +### Reactive Datasources + +The configuration property `datasource.reactive.max-size` is now applied to the whole pool. In previous versions there was a Pool for each thread, leading to applying a separate max limit to each pool in each thread. There is a single Pool shared among all threads now, which is more intuitive to use and configure. + +## Vert.x + +Quarkus 2.0 uses Vert.x 4.0. If your application relies on Vert.x APIs, check the [Vert.x migration guide](https://vert-x3.github.io/vertx-4-migration-guide/index.html). + +### Reactive Routes + +The enum of the HTTP _verb_ to configure the `methods` attribute of a `@Route` has been moved to `io.quarkus.vertx.web.Route.HttpMethod`. + +### Vert.x JSON support + +In Quarkus 2.0, Vert.x uses the Jackson Mapper managed by Quarkus. Thus, instead of configuring the JSON object mappers on the `Json` class, customize the Jackson Mapper following the instructions from https://quarkus.io/guides/rest-json#configuring-json-support. + +## Neo4j + +The `quarkus.neo4j.pool.metrics-enabled` property that enables Neo4j metrics was renamed to `quarkus.neo4j.pool.metrics.enabled` to make the naming more consistent with similar properties in other extensions. + +## Kafka + + +### Accessing the configuration + +Accessing the default configuration of the Kafka broker must use the `@Identifier` annotation, instead of `@Named`: + +```java +@ApplicationScoped +public class KafkaProviders { + + @Inject + @Identifier("default-kafka-broker") // was @Named before + Map config; +} +``` + +The `KafkaClientService.getProducer()` method no longer returns `org.apache.kafka.clients.producer.Producer`. +Instead, it returns `io.smallrye.reactive.messaging.kafka.KafkaProducer`, which exposes the most common producer methods with a `Uni`-based interface. +The underlying reason is that the Kafka connector in SmallRye Reactive Messaging now sends all records to the Kafka broker on an extra thread, to guarantee fully non-blocking behavior. + +### Dev Mode - Connecting to localhost:9092 + +By default, the Kafka client was connecting to localhost:9092 if the broker location was not configured. +In 2.0, Dev Services will start a broker and connect to this one. If you need to connect to a broker running on localhost:9092, you need to set `kafka.bootstrap.servers=localhost:9092`. + +## MongoDB + +The old `io.quarkus.mongodb.runtime.MongoClientName` annotation that has been deprecated five release ago is now removed, please use `io.quarkus.mongodb.MongoClientName` instead. + +## Reactive MongoDB with Panache + +The `persist()`, `update()` and `persistOrUpdate()` methods now return an `Uni` instead of an `Uni` to allow chainning the methods. The same has been done for the Kotlin variant as well. + +## Hibernate ORM with Panache + +The `getEntityManager()` and the `flush()` methods of `PanacheEntityBase` are now static methods. The same has been done for the Kotlin variant, those methods are now in the PanacheEntityBase companion object. + +## Hibernate reactive with Panache + +The `persist()` and `persistAndFlush()` methods now return an `Uni` instead of an `Uni` to allow chainning the methods. + +## OpenTracing JDBC instrumentation + +In Quarkus 2.0, we updated the version of the OpenTracing JDBC driver to a version that uses dynamic proxies, so not compatible by default with native image. + +So, if you're using the OpenTracing JDBC driver to instrument JDBC calls, **and deploys your application as a native image**, the easiest way to make it work is to downgrade to version 0.2.4 inside your `pom.xml`: + +```xml + + io.opentracing.contrib + opentracing-jdbc + 0.2.4 + +``` + +You can also try to register the dynamic proxy usage for native image, see the details in the following issue: https://github.com/quarkusio/quarkus/issues/18033 \ No newline at end of file diff --git a/migration/Migration-Guide-2.1.md b/migration/Migration-Guide-2.1.md new file mode 100644 index 0000000000..e710f25e26 --- /dev/null +++ b/migration/Migration-Guide-2.1.md @@ -0,0 +1,109 @@ +## Hibernate with Panache split packages + +To avoid split packages: + +* `ProjectedFieldName` has been moved from `io.quarkus.hibernate.orm.panache` to `io.quarkus.hibernate.orm.panache.common`. + +The original, now deprecated, classes haven been kept in 2.1 and will be removed in 2.2. + +## MongoDB with Panache split packages + +To avoid split packages: + +* `MongoEntity` has been moved from `io.quarkus.mongodb.panache` to `io.quarkus.mongodb.panache.common`. +* `ProjectionFor` has been moved from `io.quarkus.mongodb.panache` to `io.quarkus.mongodb.panache.common`. +* `PanacheUpdate` has been moved from `io.quarkus.mongodb.panache` to `io.quarkus.mongodb.panache.common`. +* `ReactivePanacheUpdate` has been moved from `io.quarkus.mongodb.panache.reactive` to `io.quarkus.mongodb.panache.common.reactive`. + +The original, now deprecated, classes haven been kept in 2.1 and will be removed in 2.2. + +## Config +The `@WithName` annotation for `@ConfigMapping` now correctly used the name as is to map the configuration name and not a transformed version. Example: + +```java +@ConfigMapping +interface Server { + @WithName("theHost") + String server(); +} +``` + +In Quarkus `2.x`, the `theHost` name would map to the `the-host` configuration. Starting with Quarkus `2.1` it now maps with the exact name of `theHost`. + +## Hibernate Reactive + +Hibernate Reactive **must** run on a Vert.x event loop thread. Running it on other threads has never been supported and would likely lead to difficult to identify concurrency related problems. Prior to Quarkus 2.1, despite this fact, there was no actual check in place to enforce the rule. + +Since Quarkus 2.1 there is an active guard protecting users from this mistake, so you'll see a runtime exception if you attempt to use it from the wrong thread. + +We strongly recommend trying to design Reactive applications to stick to the pure event loop as that is the most efficient and best performing solution for a reactive app. If this doesn't apply to you, please consider using the classic version of Hibernate ORM which is more suited for applications which are not running on the event loop. + +## OpenShift + +### Java command and arguments mapping + +When deploying a Quarkus application into OpenShift, by default the container configuration to run the application looked like: + +``` +command: java +args: + - '-Dquarkus.http.host=0.0.0.0' + - '-Djava.util.logging.manager=org.jboss.logmanager.LogManager' + - '-jar' + - /deployments/quarkus-run.jar +``` + +Both `command` and `args` fields can be overriden via the `quarkus.openshift.command` and `quarkus.openshift.arguments` properties. + +However, users can't simple append their custom Java arguments, for example: `java -jar /deployments/quarkus-run.jar param1 param2`. The only workaround was to copy and paste the existing content in the default `args` field and append the custom arguments `param1` and `param2`. + +This has been fixed in 2.0 by moving all the Java related parameters into the `command` field: + +``` +command: + - 'java' + - '-Dquarkus.http.host=0.0.0.0' + - '-Djava.util.logging.manager=org.jboss.logmanager.LogManager' + - '-jar' + - /deployments/quarkus-run.jar +``` + +Now, users can use the `quarkus.openshift.arguments` property to append their custom Java arguments, for example: `quarkus.openshift.arguments=param1,param2`. + + +## Kubernetes Client + +The Kubernetes Client has been upgraded to 5.6, which contains some minor breaking API changes. + +Please refer to the release notes for versions [5.6](https://github.com/fabric8io/kubernetes-client/releases/tag/v5.6.0) and [5.5](https://github.com/fabric8io/kubernetes-client/releases/tag/v5.5.0) for more details. + +## SmallRye Fault Tolerance + +Quarkus 2.1 updates SmallRye Fault Tolerance to version 5.2, which introduces a special mode, **not compatible** with the MicroProfile Fault Tolerance specification. In this mode, methods with fault tolerance annotations are automatically treated as non-blocking if they have an asynchronous return type (`CompletionStage` or `Uni`), even if they don't have any asynchronous annotation (`@Asynchronous`, `@Blocking`, `@NonBlocking`). If an annotation is present, it is of course still honored. + +Quarkus enables this non-compatible mode by default. If you need strict compatibility with MicroProfile Fault Tolerance, you can set `smallrye.faulttolerance.mp-compatibility=true`. For more information, see https://smallrye.io/docs/smallrye-fault-tolerance/5.2.1/usage/extra.html#_non_compatible_mode + +## Quarkus Universe BOM is deprecated + +In the Quarkus 2.1.0.Final release the `io.quarkus:quarkus-universe-bom` typically imported by Quarkus applications is deprecated in favor of the Quarkus platform member-specific BOMs: + +* io.quarkus.platform:quarkus-bom:2.1.0.Final +* io.quarkus.platform:quarkus-optaplanner-bom:2.1.0.Final +* io.quarkus.platform:quarkus-kogito-bom:2.1.0.Final +* io.quarkus.platform:quarkus-qpid-jms-bom:2.1.0.Final +* io.quarkus.platform:quarkus-cassandra-bom:2.1.0.Final +* io.quarkus.platform:quarkus-camel-bom:2.1.0.Final +* io.quarkus.platform:quarkus-hazelcast-client:2.1.0.Final +* io.quarkus.platform:quarkus-debezium-bom:2.1.0.Final +* io.quarkus.platform:quarkus-blaze-persistence-bom:2.1.0.Final +* io.quarkus.platform:quarkus-google-cloud-services-bom:2.1.0.Final + +The platform member-specific BOMs above are actually fragments of the legacy `io.quarkus:quarkus-universe-bom` and so it doesn't matter in which order they are imported in applications. The main advantage is that instead of enforcing all the dependency version constraints from the Quarkus "universe" BOM, applications may import only those constraints that are actually relevant to them. You can read more about this change in [the blog post introducing this change](https://quarkus.io/blog/quarkus-2x-platform-quarkiverse-registry/). + +NOTE: that the Quarkus dev tools, including [code.quarkus.io](https://code.quarkus.io), will now be generating projects importing the BOMs that are relevant to the extensions selected for the project to be created. + +The `io.quarkus:quarkus-universe-bom` is still going to be released in the upcoming versions of the Quarkus platform in addition to the member-specific BOMs to give time for the existing applications to migrate to the new BOMs. + +## Quartz + +The name of a job trigger stored in the database does not have the `_trigger` suffix anymore. As a result you'll need to either clear the Quartz trigger tables or append the `_trigger` suffix to the relevant `@Scheduler#identity()` value when migrating an application running on previous versions of Quarkus. No change is required if the `ram` job store is used, i.e. `quarkus.quartz.store-type=ram`. diff --git a/migration/Migration-Guide-2.10.md b/migration/Migration-Guide-2.10.md new file mode 100644 index 0000000000..3952d011f8 --- /dev/null +++ b/migration/Migration-Guide-2.10.md @@ -0,0 +1,62 @@ +## Keycloak Authorization and Keycloak 18.0.0 + +Keycloak version has been bumped to [18.0.0](https://www.keycloak.org/2022/04/keycloak-1800-released.html). It may affect `quarkus-keycloak-authorization` users who have authorization policies represented as `Java Script` and uploaded to Keycloak because the `upload-scripts` feature has been removed in Keycloak 18.0.0. +Please see [Keycloak Upgrading Guide](https://www.keycloak.org/docs/latest/upgrading/index.html#removal-of-the-code-upload-scripts-code-feature) for more information. + +Here is a short summary of how to manage such Java Script policies in Keycloak 18.0.0. + +Lets say you have the following authorization policy uploaded to Keycloak: + +```java + import org.keycloak.representations.idm.authorization.PolicyRepresentation; + import org.keycloak.representations.idm.authorization.ResourceServerRepresentation; + + public void uploadPolicy() { + ResourceServerRepresentation authorizationSettings = new ResourceServerRepresentation(); + PolicyRepresentation policyAdmin = createJSPolicy("Admin Policy", "var identity = $evaluation.context.identity;\n" + + "\n" + + "if (identity.hasRealmRole(\"admin\")) {\n" + + "$evaluation.grant();\n" + + "}", authorizationSettings); + // Upload this policy using Keycloak Admin Client... + } + + private static PolicyRepresentation createJSPolicy(String name, String code, ResourceServerRepresentation authorizationSettings) { + PolicyRepresentation policy = new PolicyRepresentation(); + policy.setName(name); + policy.setType("script-" + code); + authorizationSettings.getPolicies().add(policy); + return policy; + } +``` + +For it to work with Keycloak `18.0.0` the JavaScript code needs to be moved to a policy file such as `admin.js`: + +``` +var identity = $evaluation.context.identity; +if (identity.hasRealmRole("admin")) { +$evaluation.grant(); +} +``` + +and this `admin.js` needs to be referred to from the Java code: + +```java +ResourceServerRepresentation authorizationSettings = new ResourceServerRepresentation(); +PolicyRepresentation policyAdmin = createJSPolicy("Admin Policy", "admin-policy.js", authorizationSettings); +// Upload this policy using Keycloak Admin Client... +``` + +and from `keycloak-scripts.json`: + +```json +{ + "policies": [ + { + "fileName": "admin-policy.js" + } + ] +} +``` + +Finally `keycloak-scripts.json` and `admin-policy.js` need to be added to a jar and deployed to Keycloak. \ No newline at end of file diff --git a/migration/Migration-Guide-2.11.md b/migration/Migration-Guide-2.11.md new file mode 100644 index 0000000000..7440df9159 --- /dev/null +++ b/migration/Migration-Guide-2.11.md @@ -0,0 +1,59 @@ +## GraphQL endpoints are singleton by default + +Previously, the default scope attached to a `@GraphQLApi` endpoint was `@Dependent`. Now, unless you explicitly add a scope annotation to your endpoint, it will act as a `@Singleton` bean. This is thus aligned with the default behavior of JAX-RS endpoints. + +## Unification of database dev services configuration + +All database Dev Services now use the same database name, username and password: + +- Database name: `quarkus` +- Username: `quarkus` +- Password: `quarkus` + +Except for Microsoft SQL Server, for which both the database and Testcontainers are less flexible: + +- Database name: none +- Username: `SA` +- Password: `Quarkus123` + +## `jsoup` removed from `quarkus-bootstrap-bom` + +As a result of updating to Maven 3.8.6, `jsoup` was removed from `quarkus-bootstrap-bom` (`quarkus-bom` respectively). +If you are using `jsoup`, you will have to add an explicit version to the respective dependency declaration. + +## New Redis API + +Quarkus 2.11 provides a new Redis API. +Introducing this API has introduced a few breaking changes: + +* Host Providers are now identified using `@Identifier` instead of `@Named` +* It is not possible to create dynamic clients - this was done to support pub/sub, which is now supported by the API + +We recommend migrating to this new API. The old one is still available, but has been deprecated and will be removed at some point. + +To migrate to the new API, we recommend injecting the `RedisDataSource` (or `ReactiveRedisDataSource`) in a constructor and then, retrieving the _group_ of commands you need in your application: + +```java +private final KeyCommands keyCommands; +private final StringCommands countCommands; + +public IncrementService(RedisDataSource ds) { + countCommands = ds.string(Long.class); + keyCommands = ds.key(); +} +``` + +## Qute + +In previous versions, `{[` and `]}` could be used to mark the content that should be rendered but not parsed. This syntax is now removed due to common collisions with constructs from other languages. The unparsed character data can only start with the sequence `{|` and it ends with the sequence `|}`. + +## Old Liquibase xsd files removed from native image + +`dbchangelog-*.xsd` and `liquibase-pro-*.xsd` files older than 4.7 are not added to native image anymore. +If you are still referencing such old xsd files in your changelog xml files then it's time to update these `schemaLocations` to 4.13, e.g.: +```xml + +``` \ No newline at end of file diff --git a/migration/Migration-Guide-2.12.md b/migration/Migration-Guide-2.12.md new file mode 100644 index 0000000000..6e2ce85bd9 --- /dev/null +++ b/migration/Migration-Guide-2.12.md @@ -0,0 +1,20 @@ +## `quarkus.hibernate-search-orm.enabled` was renamed to `quarkus.hibernate-search-orm.active` + +If you were previously using the configuration property `quarkus.hibernate-search-orm.enabled` to enable/disable Hibernate Search at runtime (by setting the config in deployment configuration files, environment variables or commandline parameters), then you should use the configuration property `quarkus.hibernate-search-orm.active` instead. + +`quarkus.hibernate-search-orm.enabled` is now aligned with Quarkus conventions and disables the extension at *build time*, which cannot be reverted at runtime. + +## Gradle 7.5.1 + +Quarkus now requires Gradle 7.5.1. If your project is using Gradle Wrapper, make sure to [update it](https://docs.gradle.org/7.5.1/userguide/gradle_wrapper.html#sec:upgrading_wrapper). +This upgrade should solve build issues such as out of memory and non-existent tasks that have been seen with previous Gradle versions. + +## Path specific authentication for OIDC `web-app` applications + +If your application combines multiple authentication mechanisms including OIDC then please use `quarkus.http.auth.permission..auth-mechanism=code` instead of `quarkus.http.auth.permission..auth-mechanism=bearer` if you work with OIDC `web-app` applications and would like to configure an HTTP security policy to use only the OIDC authorization code flow mechanism, for example: + +``` +quarkus.http.auth.permission.bearer.paths=/web-app +quarkus.http.auth.permission.bearer.policy=authenticated +quarkus.http.auth.permission.bearer.auth-mechanism=code +``` \ No newline at end of file diff --git a/migration/Migration-Guide-2.13.md b/migration/Migration-Guide-2.13.md new file mode 100644 index 0000000000..8937c1c391 --- /dev/null +++ b/migration/Migration-Guide-2.13.md @@ -0,0 +1,66 @@ +## GraalVM CE / Mandrel migration from 22.2 to 22.3 + +Starting with 2.13.4.Final, Quarkus defaults to using GraalVM CE / Mandrel 22.3 for generating native executables. + +### Substitution (and other) annotations + +Starting with 22.3, substitution (and other) annotations located under the package `com.oracle.svm.core.annotate` have been moved from `org.graalvm.nativeimage:svm:jar` to `org.graalvm.sdk:graal-sdk:jar`. +If your code relies on any of these annotations, please update your pom files accordingly, i.e., substituting the `svm` dependency with the `graal-sdk` one. + +NOTE: If your code relies on such annotations and you want to be able to compile it with both Quarkus < 2.13.4 and >= 2.13.4, then please include both dependencies in your project, i.e.: + +```xml +... + + org.graalvm.sdk + graal-sdk + + + org.graalvm.nativeimage + svm + +... +``` + +NOTE: Some annotations, like `@AlwaysInline` have been moved from `com.oracle.svm.core.annotate` to `com.oracle.svm.core`, and are not shipped in `org.graalvm.sdk:graal-sdk:jar`. +If your code relies on such annotations, you are strongly advised to reconsider their use as they are not public API. +If, however, they turn out to be mandatory for the correct functionality of your code please make sure to update the `import` statements in your source code and include `org.graalvm.nativeimage:svm:jar` in addition to `org.graalvm.sdk:graal-sdk:jar` in the dependencies of your project. + +### Mandrel no longer providing Java 11 based releases + +Starting with 22.3, Mandrel no longer provides Java 11 based releases. +As a result, if you used Mandrel builder images with the suffix `-java11` in the past, please be advised that such images will no longer be available, thus you are encouraged to use the `-java17` suffixed ones. +Note, however, that this doesn't mean that you may no longer produce native executables with Mandrel for Java 11 projects. +You may still compile your Java 11 projects using OpenJDK 11 and produce native executables from the resulting Java 11 bytecode using the `-java17` Mandrel builder images. + +## Flyway + +`quarkus.flyway.validate-on-migrate` is now enabled by default, which will cause the deployment to fail if you have modified migrations after they have been applied. +You can either disable it, or enable `quarkus.flyway.repair-at-start` to align checksums in the history table with their current values. + +## SmallRye Reactive Messaging + +Prior to Quarkus 2.13, the Reactive Messaging consuming methods were called with an active CDI request context, inadvertently propagated, and were never terminated. Quarkus corrects this behaviour and makes sure the request context is not activated unnecessarily on message consuming methods. Code relying on the presence of the `RequestScoped` beans might need to start a request scope explicitly; for example, using `@ActivateRequestContext` annotation on the message consuming method. + +Note that using `@ActivateRequestContext` on a method creates a request context if the method is not already called on an existing request context. If a new context was created for the method, at the end of the method execution (e.g. the completion of the returned `Uni` or `CompletionStage`) the context will be destroyed, effectively disposing request scoped beans bound to it. + +## @TestHTTPResource URI + +When using @TestHTTPResource as described [here](https://github.com/quarkusio/quarkus/blob/2.13.0.CR1/docs/src/main/asciidoc/getting-started-testing.adoc#43-injecting-a-uri), the injected URI now also contains the any path that was specified in the `quarkus.http.root-path` configuration property. + +## @InjectMock + +The `quarkus-junit5-mockito` extension is internally using the `javax.enterprise.inject.spi.BeanManager#getBeans()` method to get the set of beans eligible for an `@InjectMock` injection point. +Unfortunately, the behavior of `BeanManager#getBeans()` was broken - if no qualifier was specified then any bean that matching the required type was eligible for injection. +However, the CDI specification mandates that the container must assume the `@Default` qualifier instead. +As a result, a test that injects a mock of a bean with non-`@Default` qualifier and does not specify the qualifier explicitly will fail. +A typical example is the injection of a Reactive REST Client - an `@InjectMock` injection point needs to be annotated with `@org.eclipse.microprofile.rest.client.inject.RestClient`. + +## OpenTelemetryClientFilter +The OpenTelemetryClientFilter is not required to be registered manually anymore. +Before, when creating a programatic `javax.ws.rs.client.Client` with `javax.ws.rs.client.ClientBuilder.newClient()`, this filter was required to enable OpenTelemetry Tracing to create Spans for that client. +The underlying Vert.x client, used by the reactive REST client, now adds the OpenTelemetry instrumentation, simplifying this client's creation. + +## CORS Filter returns HTTP 403 for failed preflight requests since 2.7.7.Final + +CORS filter used to return HTTP 200 status code and no Access-Control-Allow-Origin header when CORS preflight requests were failing. Now, HTTP 403 will be returned instead of 200 as well. Please update your tests which expect HTTP 200 status code for the failed preflight requests to check for HTTP 403 status code instead. \ No newline at end of file diff --git a/migration/Migration-Guide-2.14.md b/migration/Migration-Guide-2.14.md new file mode 100644 index 0000000000..5899042c1e --- /dev/null +++ b/migration/Migration-Guide-2.14.md @@ -0,0 +1,76 @@ +## GraalVM CE / Mandrel migration from 22.2 to 22.3 + +Quarkus 2.14.0.Final still defaults to GraalVM CE / Mandrel 22.2 but, starting with 2.14.1.Final, Quarkus will default to using GraalVM CE / Mandrel 22.3 for generating native executables. + +### Substitution (and other) annotations + +Starting with 22.3, substitution (and other) annotations located under the package `com.oracle.svm.core.annotate` have been moved from `org.graalvm.nativeimage:svm:jar` to `org.graalvm.sdk:graal-sdk:jar`. +If your code relies on any of these annotations, please update your pom files accordingly, i.e., substituting the `svm` dependency with the `graal-sdk` one. + +NOTE: Some annotations, like `@AlwaysInline` have been moved from `com.oracle.svm.core.annotate` to `com.oracle.svm.core`, and are not shipped in `org.graalvm.sdk:graal-sdk:jar`. +If your code relies on such annotations, you are strongly advised to reconsider their use as they are not public API. +If, however, they turn out to be mandatory for the correct functionality of your code please make sure to update the `import` statements in your source code and include `org.graalvm.nativeimage:svm:jar` in addition to `org.graalvm.sdk:graal-sdk:jar` in the dependencies of your project. + +### Mandrel no longer providing Java 11 based releases + +Starting with 22.3 Mandrel no longer provides Java 11 based releases. +As a result, if you used Mandrel builder images with the suffix `-java11` in the past, please be advised that such images will no longer be available, thus you are encouraged to use the `-java17` suffixed ones. +Note, however, that this doesn't mean that you may no longer produce native executables with Mandrel for Java 11 projects. +You may still compile your Java 11 projects using OpenJDK 11 and produce native executables from the resulting Java 11 bytecode using the `-java17` Mandrel builder images. + +## Kubernetes Client upgraded to 6.1 + +The Kubernetes Client has been upgraded from 5.12 to 6.1. +Please refer to the [Kubernetes Client 6 migration guide](https://github.com/fabric8io/kubernetes-client/blob/master/doc/MIGRATION-v6.md). + +## `@ConfigProperties` was removed + +The deprecated annotation `io.quarkus.arc.config.ConfigProperties` was removed. +Users are encouraged to use the `@io.smallrye.config.ConfigMapping` instead. +Please read the [Mapping configuration to objects](https://quarkus.io/guides/config-mappings#config-properties) for more information. + +## OpenTelemetry exporters moved + +The `quarkus-opentelemetry-exporter-jaeger` extension was moved to the [quarkus-opentelemetry-exporter](https://github.com/quarkiverse/quarkus-opentelemetry-exporter) at Quarkiverse. +The `quarkus-opentelemetry-exporter-otlp` extension was removed and the code is now part of `quarkus-opentelemetry`, as the default exporter. +Your project dependencies need to be updated accordingly. The config properties remain the same. + +## RESTEasy Reactive multipart changes + +The following changes impact multipart support in RESTEasy Reactive: + +- BREAKING: Previously, you could catch all file uploads regardless of the parameter name using the syntax: `@RestForm List all`, but this was ambiguous and unintuitive, so now this form will only fetch parameters named `all` (just like for every other form element of other types) and you have to use this form to catch every parameter regardless of its name: `@RestForm(FileUpload.ALL) List all`. +- The `@MultipartForm` annotation is now deprecated. It is now equivalent to `@BeanParam` which you may use in its stead. Multipart form parameter support has been added to `@BeanParam` +- The `@BeanParam` is now optional and implicit for any non-annotated method parameter which has fields annotated with any `@Rest*` or `@*Param` annotations. +- Multipart elements are no longer limited to being encapsulated inside `@MultipartForm`-annotated classes: they can be used as method endpoint parameters as well as endpoint class fields. +- Multipart elements now default to the `@PartType(MediaType.TEXT_PLAIN)` mime type, unless they are of type `FileUpload`, `Path`, `File`, `byte[]` or `InputStream` +- Multipart elements of the `MediaType.TEXT_PLAIN` mime type are now deserialised using the regular `ParamConverter` infrastructure (previously they were using `MessageBodyReader`) +- Multipart elements of the `FileUpload`, `Path`, `File`, `byte[]` or `InputStream` types are deserialised specially. +- Multipart elements of other mime types (explicitely set) still use the appropriate `MessageBodyReader` infrastructure. +- Multipart elements can now be wrapped in `List` in order to obtain all values of the part that have the same name. +- Any client call including `@RestForm` or `@FormParam` parameters defaults to the `MediaType.APPLICATION_FORM_URLENCODED` content type, unless they are of the `File`, `Path`, `Buffer`, `Multi` or `byte[]` types, in which case it defaults to the `MediaType.MULTIPART_FORM_DATA` content type. + +## Hibernate ORM with Panache deprecated methods removed + +The following deprecated methods from Hibernate ORM with Panache and Hibernate ORM with Panache in Kotlin was removed: + +- `io.quarkus.hibernate.orm.panache.PanacheRepositoryBase#getEntityManager(Class clazz)` +- `io.quarkus.hibernate.orm.panache.kotlin.PanacheRepositoryBase#getEntityManager(clazz: KClass)` + +Both can be replaced by `Panache.getEntityManager(Class clazz)`. + +## Hibernate Validator + +Quarkus doesn't support the manual creation of `ValidatorFactory`: you have to use the `ValidatorFactory` managed by Quarkus that you can inject via CDI. +The main reason for this decision is that a `ValidatorFactory` has to be very carefully crafted to work in native executables. + +Until now, you could still do that and handle a `ValidatorFactory` yourself (if you could make it work...). Starting with 2.14, when some component of your application tries to create a `ValidatorFactory`, we actually return the `ValidatorFactory` managed by Quarkus. This is to improve the compatibility with components creating their own `ValidatorFactory`. + +## Quartz + +If you are storing your Quartz jobs in a database via JDBC, you will have to update your `JOB_DETAILS` table as a class name has changed. + +Executing the following query will fix the issue: +``` +UPDATE JOB_DETAILS set JOB_CLASS_NAME = 'io.quarkus.quartz.runtime.QuartzSchedulerImpl$InvokerJob' WHERE JOB_CLASS_NAME = 'io.quarkus.quartz.runtime.QuartzScheduler$InvokerJob'; +``` \ No newline at end of file diff --git a/migration/Migration-Guide-2.15.md b/migration/Migration-Guide-2.15.md new file mode 100644 index 0000000000..029b7d228d --- /dev/null +++ b/migration/Migration-Guide-2.15.md @@ -0,0 +1,16 @@ +## Hibernate ORM - IN clause parameter padding + +The Hibernate ORM extension now enables IN clause parameter padding by default, improving the caching of queries containing IN clauses. + +You can disable this behavior by setting `quarkus.hibernate-orm.query.in-clause-parameter-padding` to `false`. + +## REST Data with Panache changes + +The `quarkus-hibernate-orm-rest-data-panache` and `quarkus-hibernate-reactive-rest-data-panache` extensions now support querying by entity fields and entity-named queries. To see more information about this change, you can go to section [Query parameters to list entities](https://quarkus.io/version/main/guides/rest-data-panache#query-parameters-to-list-entities) of the extension guide. + +Before these changes, the auto-generated resources were internally calling the `PanacheRepositoryBase.findAll()` and `PanacheRepositoryBase.findAll(sort)` methods. And after these changes, the auto-generated resources are now calling the `PanacheRepositoryBase.find(query, params)` and `PanacheRepositoryBase.find(query, sort, params)` methods. This is totally transparent for users, so they don't need to migrate anything. However, if you were overriding either the `findAll()` or the `findAll(sort)` methods of the entity repository, these methods won't be called by the auto-generated resources any longer. Instead, you should now use the `PanacheRepositoryBase.findAll()` and `PanacheRepositoryBase.findAll(sort)` methods. + +## CORS Filter returns HTTP 403 for failed preflight requests + +CORS filter used to return HTTP `200` status code and no `Access-Control-Allow-Origin` header when CORS preflight requests were failing. Now, HTTP `403` will be returned instead of `200` as well. +Please update your tests which expect HTTP `200` status code for the failed preflight requests to check for HTTP `403` status code instead. diff --git a/migration/Migration-Guide-2.16.md b/migration/Migration-Guide-2.16.md new file mode 100644 index 0000000000..116be7e896 --- /dev/null +++ b/migration/Migration-Guide-2.16.md @@ -0,0 +1,92 @@ +## Config + +Configuration property names set in `.env` files are now converted to their expected name, following the Environment Variables naming rules detailed in https://quarkus.io/version/2.16/guides/config-reference#environment-variables. + +## Kafka Client Dev services + +Kafka Client extension introduces `quarkus.kafka.devservices.provider` build time property for configuring the dev service image provider. +Before 2.16 strimzi images could be used by configuring the `quarkus.kafka.devservices.image-name` property to a value containing `strimzi` text. After 2.16 developers have the option to configure `quarkus.kafka.devservices.provider` to values `redpanda` (default), `strimzi` and `kafka-native` with each option having a default container image. `quarkus.kafka.devservices.image-name` can still be used to change the default image name. + +## No wildcard Origin support by default for CORS Filter + +CORS filter no longer supports all Origins by default when it is enabled and it has to be configured to allow all Origins. +For example, if, after a careful consideration, you decide that all Origins must be supported, then you can do it like this: +``` +quarkus.http.cors=true +quarkus.http.cors.origins=/.*/ +``` + +Please note that the same-site Origin requests will be supported without `quarkus.http.cors.origins` having to be configured. +Therefore configuring `quarkus.http.cors.origins` will only be required when the trusted 3rd party Origin requests should be allowed in which case allowing all Origins will be risky and unnecessary. + +## Micrometer + +By default, the metrics are now exported using the Prometheus format `application/openmetrics-text`, +you can revert to the former format by specifying the `Accept` request header to `plain/text` (`curl -H "Accept: text/plain" localhost:8080/q/metrics/`). + +## `QuarkusTransaction.run`/`QuarkusTransaction.call` are deprecated + +`QuarkusTransaction.run`/`QuarkusTransaction.call` are deprecated in favor of newly introduced, more explicit methods. Code relying on these methods should be updated as follows: + +``` +// Before +QuarkusTransaction.run(() -> { ... }); +QuarkusTransaction.call(() -> { ... }); +// After +QuarkusTransaction.requiringNew().run(() -> { ... }); +QuarkusTransaction.requiringNew().call(() -> { ... }); + + +// Before +QuarkusTransaction.run(QuarkusTransaction.runOptions() + .semantic(RunOptions.Semantic.REQUIRED), + () -> { ... }); +QuarkusTransaction.call(QuarkusTransaction.runOptions() + .semantic(RunOptions.Semantic.REQUIRED), + () -> { ... }); +// After +QuarkusTransaction.joiningExisting().run(() -> { ... }); +QuarkusTransaction.joiningExisting().call(() -> { ... }); + + +// Before +QuarkusTransaction.run(QuarkusTransaction.runOptions() + .timeout(10) + .exceptionHandler((throwable) -> { + if (throwable instanceof SomeException) { + return RunOptions.ExceptionResult.COMMIT; + } + return RunOptions.ExceptionResult.ROLLBACK; + }), + () -> { ... }); +QuarkusTransaction.call(QuarkusTransaction.runOptions() + .timeout(10) + .exceptionHandler((throwable) -> { + if (throwable instanceof SomeException) { + return RunOptions.ExceptionResult.COMMIT; + } + return RunOptions.ExceptionResult.ROLLBACK; + }), + () -> { ... }); +// After +QuarkusTransaction.requiringNew() + .timeout(10) + .exceptionHandler((throwable) -> { + if (throwable instanceof SomeException) { + return RunOptions.ExceptionResult.COMMIT; + } + return RunOptions.ExceptionResult.ROLLBACK; + }) + .run(() -> { ... }); +QuarkusTransaction.requiringNew() + .timeout(10) + .exceptionHandler((throwable) -> { + if (throwable instanceof SomeException) { + return RunOptions.ExceptionResult.COMMIT; + } + return RunOptions.ExceptionResult.ROLLBACK; + }) + .call(() -> { ... }); +``` + +See the javadoc of `QuarkusTransaction` and the [documentation of programmatic transactions](https://quarkus.io/guides/transaction#programmatic-approach) for more information. \ No newline at end of file diff --git a/migration/Migration-Guide-2.17.md b/migration/Migration-Guide-2.17.md new file mode 100644 index 0000000000..c6986dd40f --- /dev/null +++ b/migration/Migration-Guide-2.17.md @@ -0,0 +1,11 @@ + + +## 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 +``` diff --git a/migration/Migration-Guide-2.2.md b/migration/Migration-Guide-2.2.md new file mode 100644 index 0000000000..377801177b --- /dev/null +++ b/migration/Migration-Guide-2.2.md @@ -0,0 +1,15 @@ +## SmallRye Config + +SmallRye Config `@ConfigMapping` can now only be used on interfaces. Using it on classes results in a build-time exception. + +## Kubernetes Client + +The Kubernetes Client has been upgraded to 5.7, which contains some breaking changes. + +Please refer to [the release notes](https://github.com/fabric8io/kubernetes-client/releases/tag/v5.7.0) for more details. + +## Deprecated method in OIDC TenantConfigResolver + +`OidcTenantConfig io.quarkus.oidc.TenantConfigResolver#resolve(RoutingContext)` method has been deprecated and will be removed soon. + +Please use `Uni io.quarkus.oidc.TenantConfigResolver#resolve(RoutingContext, TenantConfigResolver.TenantConfigRequestContext)` instead, where `TenantConfigResolver.TenantConfigRequestContext` can be used to run the blocking tasks. \ No newline at end of file diff --git a/migration/Migration-Guide-2.3.md b/migration/Migration-Guide-2.3.md new file mode 100644 index 0000000000..6088dc7d26 --- /dev/null +++ b/migration/Migration-Guide-2.3.md @@ -0,0 +1,106 @@ +## Dev Mode Working Directory + +The working directory for dev mode has been changed from the build directory (`target/`) to the root of the project. +This makes the execution of the tests with continuous testing consistent with the tests executed via Surefire. + +To restore the previous behavior, you can define `${project.build.directory}` in the Quarkus Maven plugin configuration. + +## gRPC Server Interceptors +Global gRPC server interceptors have to be annotated with `@io.quarkus.grpc.GlobalInterceptor` since 2.3. + +Prior to Quarkus 2.3, all the CDI beans implementing `io.grpc.ServerInterceptor` where considered global interceptors, i.e. applied to all gRPC services. +Since 2.3, it is possible to make a service-specific interceptor, by adding `@io.quarkus.grpc.RegisterInterceptor(MyInterceptor.class)` on a gRPC service implementation. To easily distinguish between per-service interceptors and global ones, the aforementioned `@GlobalInterceptor` annotation has been introduced. + +## CDI `@PreDestroy` and `@PostConstruct` methods on bean classes +Fixed a bug where `@PreDestroy` and `@PostConstruct` methods declared on bean classes were considered business methods which violated [CDI specification rules](https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html#biz_method). Therefore, starting with 2.3, an invocation of these methods will no longer be intercepted by any `@AroundInvoke` interceptors declared on the bean class and/or on these lifecycle methods. + +This means that if you previously leveraged this scenario (for example to apply `@Transactional` to post construct callback), you will need to change your code. Here is an example of an approach that will still work: + +``` +@Dependent +class MyBean { + @PostConstruct + void init() { + doInit(); // Interception works for self-invocation + } + + @Transactional + void doInit() { + // ...e.g. save something in DB + } +} +``` + +## Deprecated methods in OIDC TokenStateManager + +`io.quarkus.oidc.TokenStateManager` has had its `String createTokenState(RoutingContext, OidcTenantConfig, AuthorizationCodeTokens)`, `AuthorizationCodeTokens getTokens(RoutingContext, OidcTenantConfig, String)` and `void deleteTokens(RoutingContext, OidcTenantConfig, String)` methods deprecated and these methods will be removed soon. + +Please use `Uni createTokenState(RoutingContext, OidcTenantConfig, AuthorizationCodeTokens, CreateTokenStateRequestContext)`, `Uni getTokens(RoutingContext, OidcTenantConfig, String, GetTokensRequestContext)` and `Uni deleteTokens(RoutingContext, OidcTenantConfig, String, DeleteTokensRequestContext)` instead, where the request contexts can be used to run the blocking tasks. + +## Reactive Routes + +The extension artifact id was changed from `quarkus-vertx-web` to `quarkus-reactive-routes`, i.e. you should add the following dependency in your `pom.xml`: + +``` + + io.quarkus + quarkus-reactive-routes + +``` + +NOTE: The original artifact `io.quarkus:quarkus-vertx-web` is automatically relocated to this new dependency. However, users are encouraged to update the dependency as soon as possible. + +## New `@PersistenceUnitExtension` qualifier for `TenantResolver`/`TenantConnectionResolver` + +Multi-tenancy support in Hibernate ORM relies on user-provided `TenantResolver` beans, and optionally `TenantConnectionResolver` beans. + +Starting with Quarkus 2.3, you should always use the `@PersistenceUnitExtension` CDI qualifier for such bean definitions, even when targeting the default persistence unit, and you should never use the `@PersistenceUnit` CDI qualifier for such bean definitions. + +In short, add a `@PersistenceUnitExtension` annotation for `TenantResolver` or `TenantConnectionResolver` beans targeting the default persistence unit: + +```diff ++ @PersistenceUnitExtension + @RequestScoped + public class CustomTenantResolver implements TenantResolver { + @Override + public String resolveTenantId() { + // ... + } + } +``` + +And replace the `@PersistenceUnit` annotation with a `@PersistenceUnitExtension` annotation for `TenantResolver` or `TenantConnectionResolver` beans targeting a named persistence unit: + +```diff +- @PersistenceUnit("nameOfMyPersistenceUnit") ++ @PersistenceUnitExtension("nameOfMyPersistenceUnit") + @RequestScoped + public class CustomTenantResolver implements TenantResolver { + @Override + public String resolveTenantId() { + // ... + } + } +``` + +Old bean definitions with the old qualifiers will continue to work for now, but such support will be removed in a later version of Quarkus. + +Note that `@PersistenceUnit` is still a valid annotation for injecting `EntityManager`/`EntityManagerFactory` in your components; it just shouldn't be used as a CDI qualifier for `TenantResolver`/`TenantConnectionResolver` beans. + +## Change of Default Key Encryption Algorithm for quarkus-smallrye-jwt-build + +Please note that the default key encryption algorithm for `quarkus-smallrye-jwt-build` has been changed from `RSA-OAEP-256` to `RSA-OAEP` to align with the `MP JWT 1.2` specification. + +If you need to continue using `RSA-OAEP-256` for encrypting the key encryption keys then set it like this: + +```java +// Encrypt the token +Jwt.upn("some identifier").jwe().keyAlgorithm(KeyEncryptionAlgorithm.RSA_OAEP_256).encrypt(); +``` + +or + +```java +// Inner Sign and Encrypt the token +Jwt.upn("some identifier").innerSign().keyAlgorithm(KeyEncryptionAlgorithm.RSA_OAEP_256).encrypt(); +``` \ No newline at end of file diff --git a/migration/Migration-Guide-2.4.md b/migration/Migration-Guide-2.4.md new file mode 100644 index 0000000000..063c1d7543 --- /dev/null +++ b/migration/Migration-Guide-2.4.md @@ -0,0 +1,24 @@ +## MicroProfile Config + +Injection points targeting beans annotated with `org.eclipse.microprofile.config.inject.ConfigProperties`, require to be annotated with the `org.eclipse.microprofile.config.inject.ConfigProperties` qualifier as stated in the MicroProfile specification. Previous Quarkus versions were only requiring a single `@Inject`. + +## Hibernate Reactive API changes + +This version of Quarkus updated to Hibernate Reactive `1.0.0.CR10`, in which a frequently used API changed signature; + +to open a new `Mutiny`.`Session` from a `Mutiny`.`SessionFactory` you now have: + +* `Uni openSession();` +* `Uni openSession(String tenantId);` +* `Uni openStatelessSession();` +* `Uni openStatelessSession(String tenantId);` + +N.B. the difference: they no longer return a `Mutiny.Session` directly but a Uni of such object. + +We considered giving these a new name, and deprecate the existing name, but since it's an experimental component and we really like this name we decided breaking the API was the better choice, for the long term benefits. + +A similar change was applied to the `Stage`.`SessionFactory`: all methods opening a `Stage`.`Session` are now returning a `CompletionStage`. + +## gRPC Decoupled from HTTP + +In previous versions of Quarkus adding the gRPC extension would also add the `quarkus-vertx-http` extension that would open a HTTP socket on port 8080 (as well as gRPC opening a port on 9000). This is no longer the case so if you wish to also serve content on port 8080 then you will need to install a HTTP extension such as `quarkus-vertx-http` or `quarkus-resteasy-reactive`. \ No newline at end of file diff --git a/migration/Migration-Guide-2.5.md b/migration/Migration-Guide-2.5.md new file mode 100644 index 0000000000..30a3c8443d --- /dev/null +++ b/migration/Migration-Guide-2.5.md @@ -0,0 +1,132 @@ +## Flyway + +We upgraded the Flyway dependency from 7.15 to version 8.0. Please refer to the [Flyway release notes](https://flywaydb.org/documentation/learnmore/releaseNotes#8.0.1) to see all the changes. + +One important breaking change is that Flyway deprecated the Community support for database versions older than 5 years, for example: MySQL 5.7 and PostgreSQL 9.6. Therefore, users using the Flyway community and an unsupported database will have a failure at startup similar to: + +``` +Caused by: org.flywaydb.core.internal.license.FlywayEditionUpgradeRequiredException: Flyway Teams Edition or MySQL upgrade required: +MySQL 5.7 is no longer supported by Flyway Community Edition, but still supported by Flyway Teams Edition. +``` + +## Hibernate with Panache split packages + +To avoid split packages, the following classes was deprecated in 2.1 and are now removed: + +* `io.quarkus.hibernate.orm.panache.ProjectedFieldName` has been removed in favor of `io.quarkus.hibernate.orm.panache.common.ProjectedFieldName`. + +## MongoDB with Panache split packages + +To avoid split packages, the following classes was deprecated in 2.1 and are now removed: + +* `io.quarkus.mongodb.panache.MongoEntity` has been removed in favor of `io.quarkus.mongodb.panache.common.MongoEntity`. +* `io.quarkus.mongodb.panache.ProjectionFor` has been removed in favor of `io.quarkus.mongodb.panache.common.ProjectionFor`. +* `io.quarkus.mongodb.panache.PanacheUpdate` has been removed in favor of `io.quarkus.mongodb.panache.common.PanacheUpdate`. +* `io.quarkus.mongodb.panache.reactive.ReactivePanacheUpdate` has been removed in favor of `io.quarkus.mongodb.panache.common.reactive.ReactivePanacheUpdate`. + +## Vert.x + +The `quarkus-vertx` extension no longer depends on the `quarkus-jackson` extension. +As a result, if your application depends on `quarkus-vertx` and makes use of the `io.vertx.core.json.JsonObject.mapFrom()` or the `io.vertx.core.json.JsonObject.mapTo()` methods then the `quarkus-jackson` extension should be added (either manually or as a transient dependency) to the project dependencies. + + +Quarkus 2.5 uses Vert.x 4.2.1. This release contains a few breaking changes. While some of them have been mitigated, you may use removed APIs: + +#### Incompatible changes in vertx-core + +| Element | Classification | Description | +| ------- | :------------- | :---------- | +| `Uni> MessageConsumer::registration()` | BREAKING | Method was removed.| +| `MessageConsumer MessageConsumer::registrationAndAwait()` | BREAKING | Method was removed.| +| `MessageConsumer MessageConsumer::registrationAndForget()` | BREAKING | Method was removed.| + + +#### Incompatible changes in vertx-json-schema + +| Element | Classification | Description | +| ------- | :------------- | :---------- | +| `SchemaRouter SchemaRouter::create(HttpClient, FileSystem, SchemaRouterOptions)` | BREAKING | The number of parameters of the method have changed. | + + +#### Incompatible changes in vertx-redis-client + +If you use the Quarkus Redis extension, these changes have been mitigated. However, the underlying Redis client contains the following breaking changes: + +| Element | Classification | Description | +| ------- | :------------- | :---------- | +| `Uni RedisAPI::lpop(===String===)` | BREAKING | The type of the parameter changed from 'String' to 'List'. | +| `Response RedisAPI::lpopAndAwait(===String===)` | BREAKING | The type of the parameter changed from 'String' to 'List'. | +| `void RedisAPI::lpopAndForget(===String===)` | BREAKING | The type of the parameter changed from 'String' to 'List'. | +| `Uni RedisAPI::psync(===String===)` | BREAKING | The type of the parameter changed from 'String' to 'List'. | +| `Response RedisAPI::psyncAndAwait(===String===)` | BREAKING | The type of the parameter changed from 'String' to 'List'. | +| `void RedisAPI::psyncAndForget(===String===)` | BREAKING | The type of the parameter changed from 'String' to 'List'. | +| `Uni RedisAPI::rpop(===String===)` | BREAKING | The type of the parameter changed from 'String' to 'List'. | +| `Response RedisAPI::rpopAndAwait(===String===)` | BREAKING | The type of the parameter changed from 'String' to 'List'. | +| `void RedisAPI::rpopAndForget(===java.lang.String===)` | BREAKING | The type of the parameter changed from 'String' to 'List'. | +| `void RedisConnection::close()` | BREAKING | The return type changed from 'void' to `Uni`. | + + +#### Incompatible changes in vertx-auth-oauth2 + +| Element | Classification | Description | +| ------- | :------------- | :---------- | +| class `AccessToken` | BREAKING | The class has been removed | +| class `KeycloakHelper` | BREAKING | The class has been removed | +| class `OAuth2RBAC` | BREAKING | The class has been removed | +| class `OAuth2Response` | BREAKING | The class has been removed | +| class `KeycloakRBAC` | BREAKING | The class has been removed | +| class `MicroProfileRBAC` | BREAKING | The class has been removed | +| `OAuth2FlowType OAuth2Auth::getFlowType()` | BREAKING | Method was removed | +| `OAuth2FlowType OAuth2Auth::introspectToken(String)` | BREAKING | Method was removed | +| `Uni OAuth2Auth::introspectToken(String, String)` | BREAKING | Method was removed | +| `Uni OAuth2Auth::introspectToken(String)` | BREAKING | Method was removed | +| `AccessToken OAuth2Auth::introspectTokenAndAwait(String, String)` | BREAKING | Method was removed | +| `AccessToken OAuth2Auth::introspectTokenAndAwait(String)` | BREAKING | Method was removed | +| `OAuth2Auth OAuth2Auth::introspectTokenAndForget(String, String)` | BREAKING | Method was removed | +| `OAuth2Auth OAuth2Auth::introspectTokenAndForget(String)` | BREAKING | Method was removed | +| `Uni OAuth2Auth::loadJWK(String)` | BREAKING | Method was removed | +| `void OAuth2Auth::loadJWKAndAwait(String)` | BREAKING | Method was removed | +| `OAuth2Auth OAuth2Auth::loadJWKAndForget(String)` | BREAKING | Method was removed | +| `OAuth2Auth OAuth2Auth::rbacHandler(OAuth2RBAC)` | BREAKING | Method was removed | + + +#### Incompatible changes in vertx-web-validation + +| Element | Classification | Description | +| ------- | :------------- | :---------- | +| `ValidationHandlerBuilder ValidationHandler::builder(SchemaParser)` | BREAKING | The return type changed from 'io.vertx.ext.web.validation.builder.ValidationHandlerBuilder' to 'io.vertx.mutiny.ext.web.validation.builder.ValidationHandlerBuilder'.| + + +## Qute + +### Scanning + +The `templates` directories are also scanned in all application archives and in extension runtime modules. +Previously, only the `templates` directory from the application root was considered. +Note that it's possible to exclude any file from any `templates` directory via the `quarkus.qute.template-path-exclude` configuration property. +Excluded files are neither parsed nor validated during build and are not automatically available at runtime. + +### Iteration Metadata Prefix + +The keys used to access the iteration metadata inside a loop cannot be used directly anymore. +Instead, a prefix is used to avoid possible collisions with variables from the outer scope. +By default, the alias of an iterated element suffixed with an underscore is used as a prefix. +For example, the `hasNext` key must be prefixed with `it_` inside an `{#each}` section: `{it_hasNext}`. +And must be used in a form of `{item_hasNext}` inside a `{#for}` section with the `item` element alias. + +The prefix is configurable either via `EngineBuilder.iterationMetadataPrefix()` for standalone Qute or via the `quarkus.qute.iteration-metadata-prefix` configuration property in a Quarkus application. Three special constants can be used: + +1. `` - the alias of an iterated element suffixed with an underscore is used (default); e.g. `{item_hasNext}` +2. `` - the alias of an iterated element suffixed with a question mark is used; e.g. `{item?hasNext}` +3. `` - no prefix is used - the default behavior in previous versions; e.g. `{hasNext}` + + +## REST Data Panache + +`quarkus-hibernate-orm-rest-data-panache`, `quarkus-spring-data-rest` and `quarkus-mongodb-rest-data-panache` can now work with both RESTEasy Classic (i.e. `quarkus-resteasy`) and RESTEasy Reactive (i.e. `quarkus-resteasy-reactive`) and this no longer have a hard dependency on `quarkus-resteasy`. +Users of these dependencies will now have to explicitly add `quarkus-resteasy` or `quarkus-resteasy-reactive` to their applications. + +## Spring Web + +`quarkus-spring-web` now works with both RESTEasy Classic (i.e. `quarkus-resteasy`) and RESTEasy Reactive (i.e. `quarkus-resteasy-reactive`) and this no longer have a hard dependency on `quarkus-resteasy-jackson`. +Users of `quarkus-spring-web` will now have to explicitly add `quarkus-resteasy-jackson` or `quarkus-resteasy-reactive-jackson` to their applications. \ No newline at end of file diff --git a/migration/Migration-Guide-2.6.md b/migration/Migration-Guide-2.6.md new file mode 100644 index 0000000000..9292519eed --- /dev/null +++ b/migration/Migration-Guide-2.6.md @@ -0,0 +1,169 @@ +## Extensions moved to the Quarkiverse Hub + +Once upon a time, Quarkus was a young project and we didn't have a lot of infrastructure around it to host extensions. +Thus all the extensions created then ended up in the main repository (called Core). + +Since then, we have invested a lot in setting up the Quarkiverse Hub infrastructure which allows easy collaboration on extensions that live outside of the Core repository. + +The Core repository is very large now and we have started moving extensions outside of it to make it smaller (easier to import in IDEs, faster local builds, shorter CI runs...) and also to lower the barrier to entry to contribute to these extensions: they are in small independent projects, far easier to build and contribute to. + +For all these extensions, we have put in place relocations so migration should be seamless but in any case you need to adjust your project for the future. If you are using one of these moved out extensions, you will see a warning when building your project instructing you how to fix the issue. + +If you are a user of these extensions, have a look at their respective project and don't hesitate to contribute to them and provide feedback. + +These moved out extensions are not handled the same and there are three categories. + +### Extensions moved out of the Quarkus Platform + +These extensions are not in the Quarkus Platform BOM anymore and you need to define the version yourself in your build file: + +| Component | New groupId | Current version | Repository | +| -----------| ------------| ----------------| ------------| +| Amazon Alexa | `io.quarkiverse.amazonalexa` | `1.0.1` | https://github.com/quarkiverse/quarkus-amazon-alexa | +| Artemis | `io.quarkiverse.artemis` | `1.0.3` | https://github.com/quarkiverse/quarkus-artemis | +| AWS support for Hibernate Search ORM + Elasticsearch | `io.quarkiverse.hibernatesearchextras` | `1.0.1` | https://github.com/quarkiverse/quarkus-hibernate-search-extras | +| JGit | `io.quarkiverse.jgit` | `1.1.0` | https://github.com/quarkiverse/quarkus-jgit | +| JSch | `io.quarkiverse.jsch` | `1.0.0` | https://github.com/quarkiverse/quarkus-jsch | +| Logging Sentry | `io.quarkiverse.loggingsentry` | `1.0.1` | https://github.com/quarkiverse/quarkus-logging-sentry | +| Neo4j | `io.quarkiverse.neo4j` | `1.0.2` | https://github.com/quarkiverse/quarkus-neo4j | +| Reactive Messaging HTTP | `io.quarkiverse.reactivemessaging.http` | `1.0.0` | https://github.com/quarkiverse/quarkus-reactive-messaging-http | +| Tika | `io.quarkiverse.tika` | `1.0.3` | https://github.com/quarkiverse/quarkus-tika | + + +> :warning: if you are using the `org.apache.activemq:artemis-server` or `org.apache.activemq:artemis-amqp-protocol` dependencies for your Artemis testing without defining a version, you will have build errors (their versions used to be defined in the Quarkus BOM but they have been removed from there). To solve this issue, you can import `io.quarkiverse.artemis:quarkus-artemis-bom:1.0.2` as a BOM in your project. It will define the versions of these dependencies. + +### Extensions included inside the Platform BOM + +These extensions have been included into the Platform BOM so if you are using the `io.quarkus.platform:quarkus-bom` BOM, you don't need to set the version but you still need to change the groupId. + +| Component | New groupId | New artifactId | Current version | Repository | +| -----------| ------------| ---------------| ----------------| ------------| +| Consul Config | `io.quarkiverse.config` | `quarkus-config-consul` | `1.0.1` | https://github.com/quarkiverse/quarkus-config-extensions | +| Vault | `io.quarkiverse.vault` | _same_ | `1.0.1` | https://github.com/quarkiverse/quarkus-vault | + +> :warning: The artifactId for the Consul Config extension has changed from `quarkus-consul-config` to `quarkus-config-consul` to be more consistent with the other Config extensions. + +### Extensions included inside the Platform with their own BOM + +These extensions have their own specific BOM in the Quarkus Platform. If you want to use them, you need to add it to your project. + +| Component | New groupId | BOM | Repository | +| -----------| ------------| ----| -----------| +| Amazon Services | `io.quarkiverse.amazonservices` | `io.quarkus.platform:quarkus-amazon-services-bom`:`your quarkus version` | https://github.com/quarkiverse/quarkus-amazon-services | + +> :information_source: The Amazon Services extensions are the extensions connecting to AWS services such as DynamoDB, IAM, S3... + +## Flyway + +The SQL Server integration was moved to a separate dependency. See https://flywaydb.org/documentation/database/sqlserver#java-usage. SQL Server users need to add the following dependency from now on: + +```xml + + org.flywaydb + flyway-sqlserver + +``` + +## Deprecated OIDC `TokenConfigResolver` and `TokenStateManager` methods, `quarkus.oidc.authentication.auto-refresh-timeout` property removed + +OIDC `TokenConfigResolver` methods [deprecated in 2.2](https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.2#deprecated-method-in-oidc-tenantconfigresolver) and `TokenStateManager` methods [deprecated in 2.3](https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.3#deprecated-methods-in-oidc-tokenstatemanager) have now been removed. + +It should have a minimum impact if any at all since only `TokenConfigResolver` and `TokenStateManager` methods returning `Uni` can work without blocking the IO thread and thus should be used in the real world applications. + +A long time deprecated `quarkus.oidc.authentication.auto-refresh-timeout` property has also been removed - please use a better named `quarkus.oidc.authentication.refresh-token-time-skew` from now on. + +## Access to `RoutingContext` in OIDC `SecurityIdentityAugmentor` + +The way a `Vert.x` `RoutingContext` can be accessed in the custom OIDC `SecurityIdentityAugmentor`s has changed. +If it is required then please access it as a `SecurityIdentity` attribute which will be more portable: + +``` +import javax.enterprise.context.ApplicationScoped; +import io.quarkus.security.identity.AuthenticationRequestContext; +import io.quarkus.security.identity.SecurityIdentity; +import io.quarkus.security.identity.SecurityIdentityAugmentor; +import io.quarkus.security.runtime.QuarkusSecurityIdentity; +import io.smallrye.mutiny.Uni; +import io.vertx.ext.web.RoutingContext; + +@ApplicationScoped +public class CustomOidcSecurityIdentityAugmentor implements SecurityIdentityAugmentor { + @Override + public Uni augment(SecurityIdentity identity, AuthenticationRequestContext context) { + // Instead of + // IdTokenCredential cred = identity.getCredential(IdTokenCredential.class); + // RoutingContext context = cred.getRoutingContext(); + RoutingContext context = identity.getAttribute(RoutingContext.class.getName()); + + QuarkusSecurityIdentity.Builder builder = QuarkusSecurityIdentity.builder(identity); + // Use RoutingContext as required + return Uni.createFrom().item(builder.build); + } +} +``` + +The old way of accessing `RoutingContext` as an OIDC `IdTokenCredential` or `AccessTokenCredential` property prevents the use of OIDC tokens for running the background tasks when no `RoutingContext` is available. + + +## Reactive Routes + +### _produces_ changes + +The `produces` attribute of the `@Route` annotation was only used for content negotiation. +Starting Quarkus 2.6, it is also used to indicate how `Multi` instances need to be serialized in the HTTP response. + +When a route returns a `Multi`, it can: + +* send the item one by one, without any modification (_raw_ stream) +* wrap the `Multi` as a JSON Array, where each item is sent one by one +* produce a server-sent-event stream +* produce JSON (also named ND-JSON) stream + +Before Quarkus 2.6, to express the three last possibilities you had to wrap the produced `Multi` using `ReactiveRoutes.asJsonArray`, `ReactiveRoutes.asEventStream` and `ReactiveRoutes.asJsonStream`. Unfortunately, this approach does not work when Quarkus security is enabled. + +To work around that problem, starting Quarkus 2.6, you can indicate the serialization you need using the `produces` attribute of `@Route`. If the first value of the `produces` array is `application/json`, `text/event-stream`, `application/x-ndjson` (or `application/stream+json`), the associated serialization is used. + +So, instead of: + +1. returning `ReactiveRoutes.asJsonArray(multi)`, return `multi` directly and set `produces="application/json"` +2. returning `ReactiveRoutes.asEventStream(multi)`, return `multi` directly and set `produces="text/event-stream"` +3. returning `ReactiveRoutes.asJsonStream(multi)`, return `multi` directly and set `produces="application/x-ndjson"` + +### Bean Validation JSON Format + +The format of a JSON response produced when a constraint violation occurs was changed in an incompatible way. + +If a parameter of a reactive route method violates the rules defined by Bean Validation then an HTTP 400 response is produced. +And if the request accepts the JSON payload then the response should follow the [Problem](https://opensource.zalando.com/problem/constraint-violation/) format. +However, prior to version 2.6 the produced JSON included an incorrect property: `details`. +The payload now follows the format, i.e. the property is called `detail`. + +## Native image builder changes + +The native image builders `ubi-quarkus-native-image` and `ubi-quarkus-mandrel` are now based on [ubi-micro:8.5](https://catalog.redhat.com/software/containers/ubi8/ubi-micro/5ff3f50a831939b08d1b832a) (instead of ubi-micro:8.4). +In addition, both images provide the [upx](https://upx.github.io/) tool which can be used to compress native executable. + +## gRPC Metrics changes + +gRPC metrics are now handled by the `quarkus-micrometer` extension. +gRPC server and clients metrics are automatically enabled when your application depends on the `quarkus-micrometer` extension. +In the case you do not want to collect these metrics, you can disable them using: + +```properties +quarkus.micrometer.binder.grpc-client.enabled=false +quarkus.micrometer.binder.grpc-server.enabled=false +``` + +The `quarkus.grpc.metrics.enabled` property has no effect anymore. + + +## gRPC Client Interceptors + +Global gRPC client interceptors must be annotated with `@io.quarkus.grpc.GlobalInterceptor` since 2.6. + +Prior to Quarkus 2.6, all the CDI beans implementing `io.grpc.ClientInterceptor` were considered global interceptors, i.e. applied to all injected gRPC clients. Since 2.6, it is possible to make a client-specific interceptor, by annotating the injection point of a gRPC client with the `@io.quarkus.grpc.RegisterClientInterceptor` annotation. + +## Reactive Messaging _split-package_ + +To avoid having a split package between the `smallrye-reactive-messaging-api` and `smallrye-reactive-messaging-provider`, the classes from `io.smallrye.reactive.messaging` from the `smallrye-reactive-messasing-provider` have been moved to `io.smallrye.reactive.messaging.provider`. These classes are internal / implementation-specific classes and should not have been used directly. + diff --git a/migration/Migration-Guide-2.7.md b/migration/Migration-Guide-2.7.md new file mode 100644 index 0000000000..d75c3e2055 --- /dev/null +++ b/migration/Migration-Guide-2.7.md @@ -0,0 +1,59 @@ +## JNDI disabled by default + +Except if one of the extensions you are using in your application requires it, JNDI is now disabled by default. + +You can enable it with `quarkus.naming.enable-jndi=true`. + +## Kubernetes Client / OpenShift Client + +The Kubernetes Client and OpenShift Client dependency has been updated to version 5.11.0. This version of the Fabric8 client includes some minor breaking changes. + +These are the most notable breakages: + +- Watchers now default to request bookmarks, improving 410 exceptions (if supported by API server). + If you are using the mock framework with explicit URIs, you may need to update your expected watch endpoints to include the parameter `allowWatchBookmarks=true` in your path expectations. +- `ExecListener` no longer passes the `okhttp3.Response` to `onOpen`. + `onFailure` will pass a simplified `ExecListener.Response` when possible. + +You can check the rest on the [Kubernetes Client 5.11.0 release notes](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md#note-breaking-changes-in-the-api-1). + +## Flyway + +The MariaDB/MySQL integration was moved to a separate dependency. See https://flywaydb.org/documentation/database/mysql#java-usage. MariaDB/MySQL users need to add the following dependency from now on: + +```xml + + org.flywaydb + flyway-mysql + +``` + +## Jib + +The `quarkus-container-image-jib` extension now uses a new base image when building a container image for JVM mode. +Where previously `fabric8/java-alpine-openjdk11-jre` was being used, now if the application targets Java 17, `registry.access.redhat.com/ubi8/openjdk-17-runtime:1.11` is used as the base image, otherwise `registry.access.redhat.com/ubi8/openjdk-11-runtime:1.11` is used. + +It's also worth noting that the new images do **not** run the application with the _root_ user. + +Furthermore, the working directory was changed to `/home/jboss`. + +## Mutiny + +Some 1+ year old deprecated methods have been removed in Mutiny 1.3.0. + +- `Multi.groupItems()`: use `Multi.group()` instead. +- `Multi.transform()`: use `Multi.select()` and `Multi.skip()` instead. +- `Multi.collectItems()`: use `Multi.collect()` instead. +- `Multi.onOverflow().drop(Consumer)`: use `Multi.onOverflow().invoke(Consumer).drop()` instead. +- `Uni.cache()` use `Uni.memoize()`: instead. + +## Supported Maven versions + +2.7.0.Final and 2.7.1.Final releases require Maven version 3.8.1 or later. 2.7.2.Final release reverts this requirement back to Maven 3.6.2 and later. + +## Testing + +Various changes where made to what used to the `quarkus-junit5-vertx` module. +- First of all, the name was changed to `quarkus-test-vertx`, as this module now also provides support for internal Quarkus tests (i.e the `quarkus-junit5-internal` module). +- Furthermore, the dependency on `quarkus-junit5` was removed. +- Finally, the API changed packages (from `io.quarkus.test.junit.vertx` to `io.quarkus.test.vertx`). \ No newline at end of file diff --git a/migration/Migration-Guide-2.8.md b/migration/Migration-Guide-2.8.md new file mode 100644 index 0000000000..8c5bb58f67 --- /dev/null +++ b/migration/Migration-Guide-2.8.md @@ -0,0 +1,133 @@ +## RESTEasy Reactive by default + +RESTEasy Reactive is now our default REST layer. +It supports equally well reactive and traditional blocking workloads. + +Note that RESTEasy Classic is still around so you don't have to migrate your projects to RESTEasy Reactive if you are not inclined to do so. + +One other important change is that we don't force a REST layer on you when creating apps: prior to 2.8, we were automatically adding the RESTEasy extension when creating new projects in a lot of cases. +This is not the case anymore: + +- If you create an application with no extensions (and with code examples enabled, which is the default), we will add RESTEasy Reactive automatically to show what a REST Quarkus application looks like. +- If you have defined at least one extension, we will consider you want to specify the extensions explicitly and we won't force RESTEasy Reactive on you. + +If you want a REST layer in your applications, add `resteasy-reactive` to the set of extensions you select, or most probably `resteasy-reactive-jackson`. + +To learn more about RESTEasy Reactive, see: + +- [Our introduction to writing REST services](https://quarkus.io/guides/rest-json) +- [The RESTEasy Reactive reference guide](https://quarkus.io/guides/resteasy-reactive) +- [The REST Client Reactive guide](https://quarkus.io/guides/rest-client-reactive) +- [The RESTEasy Reactive migration guide](https://quarkus.io/guides/resteasy-reactive-migration) - again, you can pursue with RESTEasy Classic if you like it! + +## `quarkus-resteasy-mutiny` deprecated + +RESTEasy Reactive supports reactive programming via Mutiny in far more comprehensive manner that classic RESTEasy, so users of `quarkus-resteasy-mutiny` are encouraged to switch to RESTEasy Reactive. + +## `quarkus-undertow-websockets` is gone + +The long time deprecated `quarkus-undertow-websockets` legacy extension is now removed. Use `quarkus-websockets` instead. + +## Assertj moved out of the BOM + +We had frequent problems with Assertj binary compatibility (running tests compiled with an older version didn't work well with the version enforced in the BOM) so we decided to move Assertj outside of the Quarkus BOM. + +That means you will have to define the version of Assertj in your own POM: + +```xml + + org.assertj + assertj-core + 3.22.0 + +``` + +## quarkus.datasource.devservices removed + +Long time deprecated `quarkus.datasource.devservices` config property has been removed. +Use `quarkus.datasource.devservices.enabled` instead. + +## Hibernate ORM MariaDB Dialect updated to 10.6 + +Hibernate ORM is now using `org.hibernate.dialect.MariaDB106Dialect` by default. +If you are working with MariaDB 10.3, 10.4 or 10.5 you should configure the following: + +``` +quarkus.hibernate-orm.dialect=org.hibernate.dialect.MariaDB103Dialect +``` + +## OpenTracing + +Some OpenTracing libraries code was moved to SmallRye OpenTracing due to lack of maintenance in the upstream projects: + +- [opentracing-jaxrs2](https://github.com/opentracing-contrib/java-jaxrs) +- [opentracing-concurrent](https://github.com/opentracing-contrib/java-concurrent) +- [opentracing-web-servlet-filter](https://github.com/opentracing-contrib/java-web-servlet-filter) +- [opentracing-tracerresolver](https://github.com/opentracing-contrib/java-tracerresolver) + +These are now removed from the Quarkus BOM and available in `io.smallrye:smallrye-opentracing-contrib` (included transitively with the Quarkus OpenTracing Extension). + +## OpenTelemetry + +- Static resources are not traced automatically anymore. To revert to the old behavior, please use the configuration `quarkus.opentelemetry.tracer.include-static-resources=true`. +- HTTP Span names now include a leading slash. This aligns with the [OpenTelemetry Semantic conventions for HTTP spans](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md) and the `http.route` tag. + +## Qute + +A `null` parameter of a loop section is treated as an empty iterable, smilarly as a `null` value is handled by an output expression. Previously a `null` parameter resulted in a `TemplateException` at runtime. + +```html +{#for item in items} <1> + {item.name} +{/for} +``` +<1> If `items` is resolved to `null` then nothing is rendered. Previously, a `TemplateException` was thrown at runtime. + + +## REST Client Reactive `ReactiveClientHeadersFactory` method change + +To align with `ClientHeadersFactory`, the `getHeaders` method now accepts `clientOutgoingHeaders` map as the second parameter. This parameter is a read-only map of header parameters specified on the client interface. +After the change the signature of the method is: +```java +public abstract Uni> getHeaders(MultivaluedMap incomingHeaders, + MultivaluedMap clientOutgoingHeaders); +``` + +## Scheduler + +Subclasses do not inherit the metadata of a `@Scheduled` method declared on a superclass anymore. The old behavior was undocumented and inconsistent; e.g. if `Scheduled#identity()` was used and the method was inherited then the build failed. + +In the following example, the `everySecond()` method is only invoked upon the instance of `Jobs`. +```java +class Jobs { + @Scheduled(every = "1s") + void everySecond() { + // ..do something + } +} +@Singleton +class MyJobs extends Jobs { +} +``` + +## Stork extension properties config moved to the `quarkus` namespace + +Stork extension configuration is now aligned with the rest of extensions. Properties are now configured under the `quarkus` namespace. +For configuring service discovery and load balancer strategies in the Stork extension, you can now use: + +```properties +quarkus.stork.my-service.service-discovery.type=consul +quarkus.stork.my-service.service-discovery.consul-host=localhost +quarkus.stork.my-service.service-discovery.consul-port=8500 + +quarkus.stork.my-service.load-balancer.type=least-response-time +quarkus.stork.my-service.load-balancer.use-secure-random=true +``` + +If a service discovery and load balancer providers want to use the same _type_ name, the implementation must be in different packages. + +## DevServices for Keycloak use Keycloak Quarkus distribution by default + +`DevServices for Keycloak` now use a `Quarkus-based` `Keycloak` distribution by default. The default image name is currently `quay.io/keycloak/keycloak:17.0.1`. If you'd like to use a `WildFly-based` `Keycloak` distribution then use a `quay.io/keycloak/keycloak:17.0.1-legacy` image name. Please note the version such as `17.0.1` will keep changing going forward. + +If you have to use an older `WildFly-based` `Keycloak` distributions then please set `quarkus.keycloak.devservices.keycloak-x-image=false` \ No newline at end of file diff --git a/migration/Migration-Guide-2.9.md b/migration/Migration-Guide-2.9.md new file mode 100644 index 0000000000..ae053a0702 --- /dev/null +++ b/migration/Migration-Guide-2.9.md @@ -0,0 +1,21 @@ +## H2 upgrade + +H2 has been upgraded from 1.4.197 to 2.1.210. + +The new version adds several reserved keywords such as `user`, `value` or `timestamp` so you might have to adjust your model if you use any of these in your table or column names. + +## HTTP compression + +HTTP compression settings have been made build time configuration so they cannot be overridden at runtime anymore. +This allows for more optimizations. + +Furthermore, not all HTTP responses are compressed by default. If compression support is enabled then the response body is compressed if: +1. A RESTEasy Reactive resource method is annotated with `@io.quarkus.vertx.http.Compressed`, or +2. A reactive route is annotated with `@io.quarkus.vertx.http.Compressed`, or +3. The `Content-Type` header is set and the value is a compressed media type as configured via `quarkus.http.compress-media-types`. + +NOTE: If the client does not support HTTP compression then the response body is not compressed. + +## Log rotation + +`quarkus.log.file.rotation.max-file-size` is now set to 10 MB by default. \ No newline at end of file diff --git a/migration/Migration-Guide-3.0.asciidoc b/migration/Migration-Guide-3.0.asciidoc new file mode 100644 index 0000000000..4ce39df59f --- /dev/null +++ b/migration/Migration-Guide-3.0.asciidoc @@ -0,0 +1,523 @@ +:toc: + +== Jakarta EE 10 + +Quarkus 3.0 is based on Jakarta EE 10, which means that: + +* Many Jakarta EE packages have been renamed from `+javax.*+` to `+jakarta.*+`. ++ +For example you will have to use `jakarta.inject.Inject` instead of `javax.inject.Inject`, +`jakarta.persistence.EntityManager` instead of `javax.persistence.EntityManager`, +`jakarta.validation.Validator` instead of `javax.validation.Validator`, +etc. +* Many corresponding implementations have been upgraded to a new major version, +which implies differences in behavior, most notably for Hibernate ORM (see below). + +We recommend you use the automatic update tool (see below) to ease the upgrade to Quarkus 3.0. + +== Automatic update tool + +Quarkus 3.0 introduces an update tool that can help you update your projects to Quarkus 3. + +This upgrade tool will, among other tasks: + +- Update the Quarkus version +- Adjust the packages to use the `jakarta.*` packages +- Adjust your dependencies in some cases +- Upgrade your Quarkiverse extensions to versions compatible with Quarkus 3.0 +- Adjust your configuration files when configuration properties have changed + +It doesn't handle everything (typically, Hibernate ORM API changes are not covered by the update tool) +but it should handle most of the tedious work. + +This update tool can be used for both Quarkus applications and Quarkus extensions, +be they Maven or Gradle projects using Java or Kotlin. + +If you are using the Quarkus CLI - which is recommended - https://quarkus.io/guides/cli-tooling#installing-the-cli[upgrade it to the latest] and run: + +[source,bash] +---- +quarkus update --stream=3.0 +---- + +If you are not using the CLI and using Maven, use the Quarkus Maven plugin to update your projects: + +[source,bash] +---- +./mvnw io.quarkus.platform:quarkus-maven-plugin:3.0.1.Final:update -N -Dstream=3.0 +---- + +If you are not using the CLI and using Gradle, use the Quarkus Gradle plugin to do so: + +[source,bash] +---- +./gradlew -PquarkusPluginVersion=3.0.1.Final quarkusUpdate --stream=3.0 +---- + +For more information, consult the https://quarkus.io/guides/update-quarkus[dedicated guide]. + +== 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: + +``` +jakarta.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: + +```java +@AlternativePriority(1) +``` + +After: + +```java +@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: + +* https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration#jakarta-persistence[It uses `jakarta.persistence.*` packages instead of `javax.persistence.*`]. +* https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration#legacy-criteria[The legacy Criteria API was removed]. +* https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration#type-system-changes[Custom types may require adjustments]. +* https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration#query[The syntax/behavior of JPQL/HQL/SQL queries changed slightly]. +* https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration#dialect-configuration-changes[Dialect configuration may require adjustments]. +* https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration#identifier-generator-structure[Additional sequences/tables may be required]. +* https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration#sequence-increment-size[Sequences definitions (the increment size in particular) may need to be adjusted]. +* https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration#property-sql-type[Various datatypes may not be serialized the same way]. +* https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration#unsupported-databases[Some databases and older database versions may not be supported anymore]. +* And more. + +Refer to https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration[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 + +Use https://quarkus.io/version/main/guides/hibernate-orm#quarkus-hibernate-orm_quarkus.hibernate-orm.quote-identifiers.strategy[`quarkus.hibernate-orm.quote-identifiers.strategy = all`] instead. + +=== The default ID generation optimizer is now `pooled-lo` + +In order to https://github.com/quarkusio/quarkus/issues/31899[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 https://quarkus.io/version/main/guides/hibernate-orm#quarkus-hibernate-orm_quarkus.hibernate-orm.mapping.id.optimizer.default[`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 https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration[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 https://github.com/quarkusio/quarkus/issues/31899[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 https://quarkus.io/version/main/guides/hibernate-orm#quarkus-hibernate-orm_quarkus.hibernate-orm.mapping.id.optimizer.default[`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. + +NOTE: Sometimes it's necessary to https://quarkus.io/version/main/guides/vertx#executing-asynchronous-code-from-a-blocking-thread[execute an asynchronous code from a blocking thread]. Quarkus provides the `VertxContextSupport#subscribeAndAwait()` util method which subscribes to the supplied `io.smallrye.mutiny.Uni` on a Vert.x duplicated context, then blocks the current thread and waits for the result. + +=== 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. streamAll()` with something similar to `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`). + +== OIDC + +=== Session cookie is encrypted by default + +OIDC session cookie which is created after an OIDC authorization code flow has completed, will now be encrypted by default starting from `3.0.2.Final`. Users are not expected to notice it in most cases. + +However, only if either `mTLS` or `private_key_jwt` (OIDC client private key is used to sign a JWT token) authentication methods are used between Quarkus and OpenId Connect Provider, then an in-memory encryption key will be generated, which might cause some pods in the application dealing with a very large number of requests failing to decrypt the session cookie, because a given pod trying to decrypt it might not be the one which encrypted it. + +In such cases one can register an encryption secret which should be 32 characters long, for example: +``` +quarkus.oidc.token-state-manager.encryption-secret=eUk1p7UB3nFiXZGUXi0uph1Y9p34YhBU +``` + +Also note that an encrypted session cookie might exceed a `4096` bytes limit which will cause some browsers ignoring it. Try one of the following in such cases: + +* Set `quarkus.oidc.token-state-manager.split-tokens=true` to have the ID, access and refresh tokens stored in separate cookies + +* Set `quarkus.oidc.token-state-manager.strategy=id-refresh-tokens` if you do not need to use the access token as a source of roles or to request `UserInfo` or propagate it to the downstream services + +* Register a custom `quarkus.oidc.TokenStateManager` CDI bean with the alternative priority set to 1. For example, custom `quarkus.oidc.TokenStateManager` can store all the tokens in a database and return a short DB pointer which Quarkus will use as a session cookie value. + +If application users access the Quarkus application from within the trusted network, the session cookie encryption can be disabled: + +``` +quarkus.oidc.token-state-manager.encryption-required=false +``` + +=== `SameSite` is `Lax` by default for OIDC session cookie + +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 https://vertx.io/docs/apidocs/io/vertx/kafka/client/serialization/package-summary.html[io.vertx.kafka.client.serialization] package. + +The `3.0` release removes this dependency. Serdes mentioned above are still provided from the https://github.com/quarkusio/quarkus/tree/main/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/serialization[io.quarkus.kafka.client.serialization] package. + +=== Split package resolution + +SmallRye Reactive Messaging proposes an https://smallrye.io/smallrye-reactive-messaging/4.3.0/concepts/testing/[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. + +=== Fixation of the Mockito `subclass` mockmaker + +Quarkus 3.0 updates Mockito to 5.x and in 5.0.0 Mockito https://github.com/mockito/mockito/releases/tag/v5.0.0[switched to the more flexible `inline` mockmaker by default]. +To preserve the mocking behavior users are used to since Quarkus 1.x and to avoid https://github.com/quarkusio/quarkus/issues/31251[memory leaks for big test suites], Quarkus 3.0 fixates the mockmaker to `subclass` instead of `inline` until the latter is fully supported in later Quarkus 3.x releases. + +If you really want to force the `inline` mockmaker: + +. add the following exclusion to your `pom.xml`: + ```xml + + io.quarkus + quarkus-junit5-mockito + + + org.mockito + mockito-subclass + + + + ``` +. add `mockito-core` to your dependencies (note: the `mockito-inline` artifact was removed in Mockito 5.3) + +== 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 + +=== Extension re-write +There are some major changes in the OpenTelemetry extension on Quarkus 3.0. + +Before 3.0 the OpenTelemetry SDK (OTel SDK) was created at build time and had limited configuration options, most notably, it could not be disabled at runtime. This can now be done by setting: `quarkus.otel.sdk.disabled=true` +Now, after some build time preparation steps, the OTel SDK itself is wired at runtime using the standard OTel Auto-configuration feature. This enables the usage of all Java OTel properties from upstream. + +We tried to maximise backyards compatibility as much as possible. + +Old properties are deprecated but, apart from the ones related with sampling, they will work transparently along with the new ones. We are mapping them during a short transition period. + +These are the property changes: + +|=== +| Deprecated attribute | Property to use + +| quarkus.opentelemetry.enabled +| quarkus.otel.enabled + +| quarkus.opentelemetry.tracer.enabled +| quarkus.otel.traces.enabled + +| quarkus.opentelemetry.propagators +| quarkus.otel.propagators + +| quarkus.opentelemetry.tracer.suppress-non-application-uris +| quarkus.otel.traces.suppress-non-application-uris + +| quarkus.opentelemetry.tracer.include-static-resources +| quarkus.otel.traces.include-static-resources + +| quarkus.opentelemetry.tracer.sampler +| quarkus.otel.traces.sampler + +| quarkus.opentelemetry.tracer.sampler.ratio +| quarkus.otel.traces.sampler.arg + +| quarkus.opentelemetry.tracer.exporter.otlp.enabled +| quarkus.otel.exporter.otlp.enabled + +| quarkus.opentelemetry.tracer.exporter.otlp.headers +| quarkus.otel.exporter.otlp.traces.headers + +| quarkus.opentelemetry.tracer.exporter.otlp.endpoint +| quarkus.otel.exporter.otlp.traces.legacy-endpoint + +|=== + +For samplers the changes are: + +If the sampler is parent based, there is no need to set, the now dropped property, `quarkus.opentelemetry.tracer.sampler.parent-based`. + +The values you need to set on `quarkus.opentelemetry.tracer.sampler` are now: + +|=== +|Old Sampler config value | New Sampler config value | New Sampler config value (If Parent based) + +|on +|always_on +|parentbased_always_on + +|off +|always_off +|parentbased_always_off + +|ratio +|traceidratio +|parentbased_traceidratio + +|=== + +Many new properties are now available. Please check the guide. + +We allowed the CDI configuration of many classes: IdGenerator, Resource attributes, Sampler and SpanProcessor. This is not available in standard OTel and we continue to provide this handy feature. +However, we are deprecating the CDI creation of the SpanProcessor through our LateBoundBatchSpanProcessor. If you are overriding or customising it, please let us know. +Currently we continue to use this processor to make sure backwards compatibility exists but we will soon move to use the standard exportes bundled with the OTel SDK. + +This means default backwards compatible exporter is using this configuration: +`quarkus.otel.traces.exporter=cdi` + +As a preview, the stock OTLP exporter is now availably by setting: +`quarkus.otel.traces.exporter=otlp` + +We now provide additional configurations of the OTel SDK using their standard SPI hooks for Sampler and SpanExporter. The remaining SPIs are available but require testing to validate compatibility. + +The OpenTelemetry Guide was also updated. + +=== OpenTelemetry Upgrades +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 https://github.com/open-telemetry/opentelemetry-java/releases/tag/v1.23.0[here] and https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/tag/v1.23.0[here]. + +=== JDBC tracing activation + +Before 3.0, to activate JDBC tracing, this configuration was used: + +``` +quarkus.datasource.jdbc.url=jdbc:otel:postgresql://localhost:5432/mydatabase +# use the 'OpenTelemetryDriver' instead of the one for your database +quarkus.datasource.jdbc.driver=io.opentelemetry.instrumentation.jdbc.OpenTelemetryDriver +``` + +Now, a much simpler configuration is required: + +``` +quarkus.datasource.jdbc.telemetry=true +``` +This doesn't require changing the db url or declare a different driver. + + +== 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. + +== OpenAPI + +- OpenAPI no longer enables a wildcard `*` `CORS` `Origin` support by default as it can leak OpenAPI documents. If you'd like, you can enable a https://quarkus.io/guides/http-reference#support-all-origins-in-devmode[wildcard `Origin` support in devmode]. + +== Scheduler/Quartz + +The `quarkus.quartz.start-mode` property is deprecated and should be replaced with https://quarkus.io/guides/scheduler-reference#quarkus-scheduler_quarkus.scheduler.start-mode[`quarkus.scheduler.start-mode`]. Note that the new https://quarkus.io/guides/scheduler-reference#programmatic_scheduling[Programmatic Scheduling API] works in both: the `quarkus-scheduler` and the `quarkus-quartz` extensions, i.e. the start mode is a shared feature available in these extensions. + +== Dev tools + +=== Maven versions + +- The lowest supported Maven version has changed from 3.6.2 to 3.8.2 following a refactoring of the Quarkus Maven plugins to support Maven 3.9. + +=== 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 https://github.com/quarkusio/quarkus-updates/commit/b39e47f06811239a3b011ab9e68b403238d3887f[here]) + +== MapStruct + +If you are using the CDI component model in MapStruct, there are a few things you need to do: + +- Update to MapStruct 1.5+ +- Update your `@Mapper(componentModel = "cdi")` annotations to `@Mapper(componentModel = "jakarta")`. \ No newline at end of file diff --git a/migration/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration.asciidoc b/migration/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration.asciidoc new file mode 100644 index 0000000000..5901f2b067 --- /dev/null +++ b/migration/Migration-Guide-3.0:-Hibernate-ORM-5-to-6-migration.asciidoc @@ -0,0 +1,410 @@ +:toc: + +== What is this? + +This guide is intended as a quick reference about the most common issues when migration from Hibernate ORM 5.6 to 6.2 in the context of Quarkus (Quarkus 2 to 3). + +It is *not* intended as a complete reference, but should be updated regularly based on issues most reported by the community. + +For a complete reference, refer to the official Hibernate ORM migration guides: + +* https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc[From Hibernate ORM 5.6 to 6.0] +* https://github.com/hibernate/hibernate-orm/blob/6.1/migration-guide.adoc[From Hibernate ORM 6.0 to 6.1] +* https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc[From Hibernate ORM 6.1 to 6.2] + +For changes related to Quarkus specifically, and not to the Hibernate ORM 5.6 -> 6.2 migration, +see link:++https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0#jpa--hibernate-orm++[the main migration guide]. + +== [[api]]API + +=== [[jakarta-persistence]]Packages and hints: `javax.persistence.*` becomes `jakarta.persistence.*` + +Affected applications:: +Any application using JPA directly. The vast majority of Hibernate ORM applications use JPA directly to some extent. ++ +Such application would import JPA packages (`import javax.persistence.<something>;`) +or use JPA query hints (`query.setHint("javax.persistence.<something>", ...)`) +Breaking changes:: +Hibernate ORM 6 implements Jakarta Persistence instead of Java EE Persistence API. ++ +See https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#jakarta-persistence[here] for more information. +Symptoms:: +* Compilation failure. +* Ignored query hints. +Actions:: +* Replace all references to packages `javax.persistence.*` with `jakarta.persistence.*` +* Replace all references to https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#jpql-query-hints[query hints] starting with `javax.persistence.*` with `jakarta.persistence.*`. +Alternatively (and preferably), use constants from `org.hibernate.jpa.AvailableHints` instead of hardcoding the hint names. + +=== [[legacy-criteria]]Legacy Hibernate Criteria API + +Affected applications:: +Any application importing legacy Hibernate Criteria API types. ++ +Such applications would necessarily call `Session#createCriteria` at some point. +Breaking changes:: +The deprecated, legacy Hibernate Criteria API (`org.hibernate.Criteria`) has been removed. ++ +See https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#legacy-hibernate-criteria-api[here] for more information. +Symptoms:: +Compilation failure. +Actions:: +Migrate existing code that relies on legacy Hibernate Criteria API to the https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#criteria[JPA Criteria API]. + +=== [[type-system]]Type system changes + +Affected applications:: +Any application relying on custom types. ++ +Such application would include classes that implement `BasicType`, `UserType`, `CompositeUserType`, `JavaTypeDescriptor`, `SqlTypeDescriptor` or similar, +or register such classes through custom dialects or `@TypeDef`, +or refer to such classes with `@Type`/`@CollectionId#type`/`@AnyMetaDef#metaType`/`@AnyMetaDef#idType`. +Breaking changes:: +Custom type interfaces and abstract classes changed, requiring adjustments to implementations. ++ +Type reference annotations changed (some were removed, some had their attributes change), +requiring adjustments to explicit type uses. ++ +See https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#type-system[here] for more information. +Symptoms:: +Compilation failure in custom type implementations and/or type references through `@TypeDef`/`@Type`/etc. +Actions:: +. Double-check that you still need custom types. Hibernate ORM 6 provides more built-in types than ever: +** https://github.com/hibernate/hibernate-orm/blob/6.1/migration-guide.adoc#basic-arraycollection-mapping[Collections/arrays of basic values are stored as native database arrays] +where supported, by default. +** https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#datatype-for-enums[Enums are stored as native database enums] +where supported, by default. +** https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#timezone-and-offset-storage[`ZonedDateTime`, `OffsetDateTime`] +and https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#offsettime-mapping-changes[`OffsetTime`] +are stored as a `timestamp with time zone` where supported, by default. +** https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#instant-mapping-changes[`Instant` is stored as a `timestamp with time zone`] +where supported, by default. +** https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#uuid-mapping-changes[UUIDs are stored using native database types] +where supported (e.g. https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#uuid-mapping-changes-on-mariadb[MariaDB] +or https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#uuid-mapping-changes-on-sql-server[Microsoft SQL Server]), by default. +** https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#basic-bytearray[Binary]/link:https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#basic-String[text] types are mapped to the most appropriate native database type depending on their length, +so for example `@Column(length = org.hibernate.Length.LONG32)` will be mapped to `text` on PostgreSQL, by default. +** You can https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#basic-bitset-jdbc-type[select database types explicitly] +by annotating properties e.g. with `@JdbcTypeCode(SqlTypes.LONG32VARCHAR)` +(which would map to `text` on PostgreSQL). +** And more. In general, try removing your custom type and check (in a development environment) if Hibernate ORM generates what you need, +and if not you can also try to force the database type with `@JdbcTypeCode(SqlTypes.)`. +. If you still need a custom type, refer to https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#basic-bitset[this guide] +to find out the appropriate solution in Hibernate ORM 6. + +=== [[query]]Query syntax/behavior changes + +Affected applications:: +Any application using JPQL/HQL/SQL strings for queries, or equivalent `Criteria` queries, and relying on the syntax elements listed below. +Breaking changes:: +Hibernate ORM 6 made a few changes to the HQL syntax: +. The optional `from` keyword (`update from MyEntity e set e.attr = null`) https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#from-token-now-disallowed-for-update[is now disallowed for `update` queries]. +. Comparing entities directly to IDs is no longer allowed, be it https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#query-path-comparison[root entities] (`where myentity = :param`) or https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#association-comparisons[associations] (`where myentity.association = :param`). +. `count()` in native queries https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#sql-bigintcount-mapping-changes[will now return a `Long` instead of a `BigInteger`]. +. Collection pseudo-attributes such as `.size`, `.elements`, `.indices`, `.index`, `.maxindex`, `.minindex`, `.maxelement`, `.minelement` https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#collection-pseudo-attributes[are not longer supported]. +Symptoms:: +Runtime exceptions, either while parsing the query (for no-longer-supported syntax elements) or when converting the result type (for `count()`). +Actions:: +. Remove the `from` keyword from your `update` queries: `update from MyEntity e set e.attr = null` => `update MyEntity e set e.attr = null`. +. Reference identifiers explicitly instead of referencing entities where identifier comparisons are involved: `where myentity = :param` => `where myentity.id = :param`, `where myentity.association = :param` => `where myentity.association.id = :param`. +. Adjust your native queries returning `count()` to expect a result of type `Long` instead of `BigInteger`. +. Replace collection pseudo-attributes with the equivalent functions: +** `mycollection.size` => `size(mycollection)` +** `mycollection.elements` => `value(mycollection)` +** `mycollection.indices` => `index(mycollection)` (for lists) or `key(mycollection)` (for maps) +** `mycollection.maxindex` => `maxindex(mycollection)` +** `mycollection.minindex` => `minindex(mycollection)` +** `mycollection.maxelement` => `maxelement(mycollection)` +** `mycollection.minelement` => `minelement(mycollection)` + +== [[configuration]]Configuration + +=== [[dialect]]Dialect configuration changes + +Affected applications:: +Any application configuring a Hibernate ORM dialect explicitly. ++ +Such application would use the configuration property `quarkus.hibernate-orm.dialect` in `application.properties`/`application.yaml`, +or the configuration property `hibernate.dialect` in `persistence.xml`. +Breaking changes:: +Hibernate ORM 6 is now able to handle multiple versions and spatial variants of a database within a single dialect class; +as a result, version-specific and spatial-specific dialect classes such as `org.hibernate.dialect.PostgreSQL91Dialect` +or `org.hibernate.spatial.dialect.postgis.PostgisPG94Dialect` +are deprecated and will lead to warnings on startup. ++ +See https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#version-specific-and-spatial-dialects[here] for more information. ++ +Additionally, some dialects have moved to a new Maven artifact, `org.hibernate.orm:hibernate-community-dialects`, +because they are <>. ++ +See https://github.com/hibernate/hibernate-orm/blob/6.0/dialects.adoc#dialects[here for more information about dialects that are supported in Hibernate ORM Core], +and https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#removal-of-support-for-legacy-database-versions[here for more information about supported versions]. ++ +Finally, the Quarkus-specific H2 dialect `io.quarkus.hibernate.orm.runtime.dialect.QuarkusH2Dialect` +was removed as it is no longer necessary. +Symptoms:: +* Deprecation warning about the dialect on startup. +* Build or startup failure if the application attempts to use dialects that have been removed +such as `io.quarkus.hibernate.orm.runtime.dialect.QuarkusH2Dialect` +or that moved to `hibernate-community-dialects`. +Actions:: +. Change the configuration property `quarkus.hibernate-orm.dialect` (in `application.properties`) / `hibernate.dialect` (in `persistence.xml`): +** If you use `application.properties`, +and your database is https://quarkus.io/version/main/guides/hibernate-orm#hibernate-dialect-supported-databases[officially supported in Quarkus], +and you used the dialect for a <>: +*** Remove the configuration property: it is no longer necessary and will be inferred automatically. +** Otherwise, if you used a dialect for a <>: +*** Switch to the corresponding version-independent dialect class, +e.g. `org.hibernate.dialect.CockroachDialect` instead of `org.hibernate.dialect.CockroachDB201Dialect`. +** Otherwise (i.e. you used a dialect for a <>,): +*** Add a Maven/Gradle dependency to `org.hibernate.orm:hibernate-community-dialects`. +*** Switch to the relevant version-independent dialect class, +e.g. `org.hibernate.community.dialect.OracleLegacyDialect` instead of `org.hibernate.dialect.Oracle9iDialect` +or `org.hibernate.community.dialect.MariaDBLegacyDialect` instead of `org.hibernate.dialect.MariaDB102Dialect`. +*** Seriously consider <>, +because your application might stop working at any moment with the next versions of Quarkus. +. Set the database version through configuration property https://quarkus.io/guides/datasource#quarkus-datasource_quarkus.datasource.db-version[`quarkus.datasource.db-version`] (in `application.properties`) +/ `jakarta.persistence.database-product-version` (in `persistence.xml`). + +== [[database-schema]]Database schema and data serialization/deserialization changes + +=== [[database-orm-compatibility]]Best-effort Hibernate ORM 5.6 compatibility switch + +If you are in a hurry and want to address API/behavior issues and keep (most) schema changes for later, +you can take advantage of the https://github.com/quarkusio/quarkus/pull/31540[Hibernate ORM 5.6 database compatibility switch]: + +```properties +quarkus.hibernate-orm.database.orm-compatibility.version = 5.6 +``` + +When this property is set, Quarkus attempts to configure Hibernate ORM +to exchange data with the database as the given version of Hibernate ORM would have, +*on a best-effort basis*. + +[WARNING] +==== +* Schema validation may still fail in some cases: +this attempts to make Hibernate ORM 6+ behave correctly at runtime, +but it may still expect a different (but runtime-compatible) schema. +* This does not address *every* breaking change. +For example, <> +will still not work correctly unless you take additional steps. +* Robust test suites are still useful and recommended: +you should still check that your application behaves as intended with your legacy schema. +* This feature is inherently unstable: +some aspects of it may stop working in future versions of Quarkus, +and older versions will be dropped as Hibernate ORM changes pile up +and support for those older versions becomes too unreliable. +* You should still plan a migration of your schema to a newer version of Hibernate ORM. +For help with migration, refer to the rest of this guide. +==== + +=== [[identifier-generator-structure]]One identifier generator (sequence/table) per entity hierarchy instead of a single `hibernate_sequence` + +NOTE: This is addressed by the <>. + +Affected applications:: +* Any application defining an entity that extends `PanacheEntity` +* Any application defining an entity that uses `@GeneratedValue` on an entity identifier +without assigning an identifier generator explicitly +(no `@SequenceGenerator`/`@TableGenerator`/`@GenericGenerator`). +Breaking changes:: +Hibernate ORM will now assign a distinct identifier generator +to each entity hierarchy by default. ++ +This means Hibernate ORM will expect a different database schema, +where each entity hierarchy has its own sequence, for example, +instead of a single `hibernate_sequence` for all entities. ++ +See https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#implicit-identifier-sequence-and-table-name[here] for more information. +Symptoms:: +* If schema validation is enabled, it will fail, mentioning missing or undefined sequences/tables, e.g. `ERROR: relation "hibernate_sequence" does not exist`. +* Otherwise, SQL import scripts or persisting new entities will fail with exceptions referring to missing or undefined sequences/tables. +Actions:: +. Start your application with the setting `quarkus.hibernate-orm.database.generation=validate` +to have Hibernate ORM log all schema incompatibilities, +which will list all sequences that are missing. +Depending on your mapping (e.g. if your mapping defines an identifier generator explicitly for each entity), +there may not be any. +. Optionally, if the sequence/table names used by Hibernate ORM by default are not to your liking, configure the identifier generation of each entity explicitly: +https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-sequence[sequence], https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-identity[identity column] or https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-table[table]. When using Panache, such (advanced) configuration requires https://quarkus.io/guides/hibernate-orm-panache#custom-ids[extending `PanacheEntityBase` instead of `PanacheEntity`]. +. Update your database schema: +** Use DDL (SQL such as `create sequence [...]`) to create the missing sequences/tables. +** Use DDL to initialize sequences/tables with the right value (essentially `max(id) + 1`). +. Update any initialization script (e.g. `import.sql`) to work with the per-entity sequences instead of `hibernate_sequence`. + +=== [[sequence-increment-size]]Increment size for sequences defaults to 50 instead of 1 + +NOTE: This is addressed by the <>. + +Affected applications:: +* Any application defining an entity that extends `PanacheEntity` +* Any application defining an entity that uses `@GeneratedValue` on an entity identifier +without assigning an identifier generator explicitly +(no `@SequenceGenerator`/`@TableGenerator`/`@GenericGenerator`). +* Any application defining an entity that uses `@GeneratedValue` on an entity identifier +with the corresponding identifier generator defined with `@GenericGenerator`, +using database sequences and an explicitly defined increment size. +Breaking changes:: +Hibernate ORM will now default to 50 instead of 1 for the increment size of sequences. ++ +Upon retrieving the next value of a sequence, +Hibernate ORM will https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-optimizer[pool the retrieved value as well as the 49 next ones] to use them as identifier IDs (Quarkus defaults to the `pooled-lo` optimizer). ++ +See https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#defaults-for-implicit-sequence-generators[here] for more information. +Symptoms:: +* If schema validation is enabled, it will fail, mentioning an incorrect increment size for your sequences (actual 1, expected 50). +* Otherwise, SQL import scripts or persisting new entities will fail with exceptions referring to duplicate keys or violated primary key constraints. +Actions:: +. Update your database schema: +** Use DDL (SQL such as `alter sequence [...]`) to set the increment size of your sequences to the right value, i.e. to the allocation size of your identifier generators, which defaults to 50 since Hibernate ORM 6. +. If your use data import scripts and your application/tests assume that certain entities have a certain identifier, **do not simply use `nextval('mysequence')` as its may no longer return the value you expect**. Just hardcode those entity identifiers in your data import scripts and reset the relevant sequences at the end of the script. ++ +E.g. this: ++ +```sql +INSERT INTO hero(id, name, otherName, picture, powers, level) +VALUES (nextval('hibernate_sequence'), 'Chewbacca', '', 'https://www.superherodb.com/pictures2/portraits/10/050/10466.jpg', + 'Agility, Longevity, Marksmanship, Natural Weapons, Stealth, Super Strength, Weapons Master', 5); +``` ++ +Should become this: ++ +```sql +-- Hardcode the ID of the first Hero to the value "1", since the tests expect that value. +INSERT INTO hero(id, name, otherName, picture, powers, level) +VALUES (1, 'Chewbacca', '', 'https://www.superherodb.com/pictures2/portraits/10/050/10466.jpg', + 'Agility, Longevity, Marksmanship, Natural Weapons, Stealth, Super Strength, Weapons Master', 5); +-- Set the current value of the sequence so that the IDs of newly +-- created entities won't conflict with the hardcoded identifiers above. +ALTER SEQUENCE hero_seq RESTART WITH (select max(id) + 1 from hero); +``` + ++ +Alternatively, if you do not wish to benefit from pooled identifier generation, +set increment sizes explicitly in your mapping when you define identifier generators, +using for example `@SequenceGenerator(..., allocationSize = 1)` instead of `@GenericGenerator`. +See https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-sequence-configured[here] +for more information. + +=== [[property-sql-type]]`enum`, `Duration`, `UUID`, `Instant`, `ZonedDateTime`, `OffsetDateTime`, `OffsetTime` properties may be persisted/loaded differently + +NOTE: This is addressed by the <>, +except for enum properties whose schema validation will fail but which should work correctly at runtime. + +Affected applications:: +Any application with an entity property of the following types, +unless it overrides the SQL type with `@Type`/`@JdbcType`: +* any enum type, unless the property is annotated with `@Enumerated(STRING)` +* `Duration` +* `UUID` +* `Instant` +* `ZonedDateTime` +* `OffsetDateTime` +* `OffsetTime` +Breaking changes:: +Hibernate ORM will now map those Java types to different JDBC types, which depending on your database may map to a different SQL type: +* enum types now map to `SqlTypes.TINYINT`, `SqlTypes.SMALLINT` or a native enum type depending on the number of values and database support for enums, +instead of `Types.TINYINT` in Hibernate ORM 5. +* `Duration` maps to `SqlTypes.INTERVAL_SECOND`, instead of `Types.BIGINT` in Hibernate ORM 5. +* `UUID` maps to `SqlTypes.UUID`, instead of `Types.BINARY` in Hibernate ORM 5. +* `Instant` maps to `SqlTypes.TIMESTAMP_UTC`, instead of `Types.TIMESTAMP` in Hibernate ORM 5. +* `ZonedDateTime` and `OffsetDateTime` map to `SqlTypes.TIMESTAMP_WITH_TIMEZONE` instead of `Types.TIMESTAMP` in Hibernate ORM 5. +Additionally, if the database does not properly store timezones, values are normalized to UTC upon persisting, +instead of the Hibernate ORM 5 behavior that was to normalize to the timezone configured through `quarkus.hibernate-orm.jdbc.timezone`, defaulting to the JVM timezone. +* `OffsetTime` maps to `SqlTypes.TIME_WITH_TIMEZONE` instead of `Types.TIME` in Hibernate ORM 5. +Additionally, if the database does not properly store timezones, values are normalized to UTC upon persisting, +instead of the Hibernate ORM 5 behavior that was to normalize to the timezone configured through `quarkus.hibernate-orm.jdbc.timezone`, defaulting to the JVM timezone. ++ +For more information, see https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#duration-mapping-changes[here for `Duration], +https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#uuid-mapping-changes[here for `UUID`] +(and more specifically https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#uuid-mapping-changes-on-mariadb[here for `UUID` on MariaDB] +and https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#uuid-mapping-changes-on-sql-server[here for `UUID` on SQL Server]), +https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#instant-mapping-changes[here for `Instant`], +https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#datatype-for-enums[here for enums] +(more context https://github.com/hibernate/hibernate-orm/blob/6.1/migration-guide.adoc#enum-mapping-changes[here]), +https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#timezone-and-offset-storage[here for `ZonedDateTime` and `OffsetDateTime`], +https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#ddl-offset-time[here for `OffsetTime`]. +Symptoms:: +* If schema validation is enabled, it may fail, mentioning an incorrect type for your columns. +* Otherwise: +** For enum types, if your database supports native enum types (e.g. MySQL), persisting and loading entities will fail; otherwise they should work despite the discrepancy between your database schema and the one expected by Hibernate ORM. +** For `ZonedDateTime`, `OffsetDateTime` and `OffsetTime`, if you were previously effectively using a normalization timezone (`quarkus.hibernate-orm.jdbc.timezone` or JVM timezone) different from UTC, values loaded from the database may be incorrect. +** For all other types, persisting and loading should work correctly despite the discrepancy between your database schema and the one expected by Hibernate ORM. +Actions:: +. Start your application with the setting `quarkus.hibernate-orm.database.generation=validate` to have Hibernate ORM log all schema incompatibilities, which will list all columns with an incorrect type. +. Update your database schema: +** Use DDL (SQL such as `alter table [...] alter column [...]`) to set the type of your columns to the right value. +Depending on your database this might require multiple steps, e.g. renaming the old column, creating the new column, copying the data from the old to the new column, and finally deleting the old column. +. For `ZonedDateTime`, `OffsetDateTime` and `OffsetTime`, if you were previously effectively using a normalization timezone (`quarkus.hibernate-orm.jdbc.timezone` or JVM timezone) different from UTC: +** Use SQL `UPDATE` statements to convert data to the timezone expected by Hibernate ORM (UTC). +** Alternatively, configure timezone storage explicitly through configuration property https://quarkus.io/guides/hibernate-orm#quarkus-hibernate-orm_quarkus.hibernate-orm.mapping.timezone.default-storage[`quarkus.hibernate-orm.mapping.timezone.default-storage`]; setting it to `normalize` will give you Hibernate ORM 5's behavior. + +=== [[unsupported-databases]]Some databases and older database versions are no longer supported in Hibernate ORM + +WARNING: This is **not** addressed by the <>. + +Affected applications:: +Any application configuring a Hibernate ORM dialect explicitly, +and using a dialect that targets either a unsupported database or an unsupported version of a supported database +(see below for databases and versions supported in Hibernate ORM). ++ +Such application would use the configuration property `quarkus.hibernate-orm.dialect` in `application.properties`/`application.yaml`, +or the configuration property `hibernate.dialect` in `persistence.xml`. +Breaking changes:: +Hibernate ORM 6 dropped official support for some databases, +either fully or only for older versions. ++ +See https://github.com/hibernate/hibernate-orm/blob/6.0/dialects.adoc#dialects[here for more information about dialects that are supported in Hibernate ORM Core], +and https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#removal-of-support-for-legacy-database-versions[here for more information about supported versions]. ++ +[NOTE] +==== +Quarkus itself has stricter database and version restrictions. +In Quarkus 3.0, we expect the following databases with the following minimum version to work out-of-the-box: + +* DB2 10.5 and later. +* Apache Derby 10.14 and later. +* MariaDB 10.6 and later. +* Microsoft SQL Server 2016 and later. +* MySQL 8 and later. +* Oracle 12 and later. +* PostgreSQL 10.0 and later. +* H2 with the exact version defined in the Quarkus BOM. + +Other database and versions may or may not work, +may require additional configuration, +and may suffer from limitations such as not working in native mode. +==== ++ +Additionally, upgrades to newer database versions may involve schema changes, +as Hibernate ORM dialects targeting newer database versions +may have different default schema expectations: + +* MariaDB: +** `MariaDBDialect` uses sequences by default for identifier generation, +which is compatible with `MariaDB106Dialect` (the default in Quarkus 2) and `MariaDB103Dialect`, +but not compatible with `MariaDB102Dialect` (which uses ID generation tables). +* Other databases: +** No information at the moment. Feel free to open an issue to suggest more information to add to this guide. +Symptoms:: +* Deprecation warning about the dialect on startup. +* Build or startup failure if the application attempts to use dialects that moved to `hibernate-community-dialects`. +Actions:: +. Follow instructions to <> for backwards-compatible behavior. +. If you use an older version of a supported database, seriously consider upgrading +because your application might stop working at any moment with the next versions of Quarkus. +This may involve changes to your database schema: +** MariaDB < 10.2 to 10.3 and newer: +... Optionally, configure the identifier generation of each entity explicitly: +https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-sequence[sequence], https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-identity[identity column] or https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-table[table]. +... Start your application with the setting `quarkus.hibernate-orm.database.generation=validate` +to have Hibernate ORM log all schema incompatibilities, +which will list all sequences that are missing. +Depending on your mapping (e.g. if your mapping defines an identifier generator explicitly for each entity), +there may not be any. +... Update your database schema: +**** Use DDL (SQL such as `create sequence [...]`) to create the missing sequences. +**** Use DDL to initialize sequences with the right value (essentially `max(id) + 1`). +** Other databases: +*** No information at the moment. Feel free to open an issue to suggest more information to add to this guide. diff --git a/migration/Migration-Guide-3.1.asciidoc b/migration/Migration-Guide-3.1.asciidoc new file mode 100644 index 0000000000..5876049dba --- /dev/null +++ b/migration/Migration-Guide-3.1.asciidoc @@ -0,0 +1,76 @@ +:toc: + +== Automatic update tool + +Quarkus 3.0 introduced an update tool that can help you update your projects to new versions of Quarkus. + +We recommend you to use this tool for all upgrades, even minor ones. + +It doesn't handle everything but it should handle most of the tedious work. + +This update tool can be used for both Quarkus applications and Quarkus extensions, +be they Maven or Gradle projects using Java or Kotlin. + +If you are using the Quarkus CLI - which is recommended - upgrade it to the latest first and then run: + +[source,bash] +---- +quarkus update --stream=3.1 +---- + +If you are not using the CLI and using Maven, use the Quarkus Maven plugin to update your projects: + +[source,bash] +---- +./mvnw io.quarkus.platform:quarkus-maven-plugin:3.1.0.Final:update -N -Dstream=3.1 +---- + +If you are not using the CLI and using Gradle, use the Quarkus Gradle plugin to do so: + +[source,bash] +---- +./gradlew -PquarkusPluginVersion=3.1.0.Final quarkusUpdate --stream=3.1 +---- + +For more information, consult the https://quarkus.io/guides/update-quarkus[dedicated guide]. + +== OIDC + +=== Session cookie is encrypted by default + +OIDC session cookie which is created after an OIDC authorization code flow has completed, will now be encrypted by default. Users are not expected to notice it in most cases. + +However, only if either `mTLS` or `private_key_jwt` (OIDC client private key is used to sign a JWT token) authentication methods are used between Quarkus and OpenId Connect Provider, then an in-memory encryption key will be generated, which might cause some pods in the application dealing with a very large number of requests failing to decrypt the session cookie, because a given pod trying to decrypt it might not be the one which encrypted it. + +In such cases one can register an encryption secret which should be 32 characters long, for example: +``` +quarkus.oidc.token-state-manager.encryption-secret=eUk1p7UB3nFiXZGUXi0uph1Y9p34YhBU +``` + +Also note that an encrypted session cookie might exceed a `4096` bytes limit which will cause some browsers ignoring it. Try one of the following in such cases: + +* Set `quarkus.oidc.token-state-manager.split-tokens=true` to have the ID, access and refresh tokens stored in separate cookies + +* Set `quarkus.oidc.token-state-manager.strategy=id-refresh-tokens` if you do not need to use the access token as a source of roles or to request `UserInfo` or propagate it to the downstream services + +* Register a custom `quarkus.oidc.TokenStateManager` CDI bean with the alternative priority set to 1. For example, custom `quarkus.oidc.TokenStateManager` can store all the tokens in a database and return a short DB pointer which Quarkus will use as a session cookie value. + +If application users access the Quarkus application from within the trusted network, the session cookie encryption can be disabled: + +``` +quarkus.oidc.token-state-manager.encryption-required=false +``` + +=== ID token audience is verified by default + +ID token `aud` (audience) claim will now be verified by default - it is expected to be equal to the configured `quarkus.oidc.client-id` property value https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation[as required by the OIDC specification]. + +You can override an expected ID token audience value with a `quarkus.oidc.token.audience` configuration property. You can set `quarkus.oidc.token.audience` to `any` - but do it only if you are dealing with a non-compliant OIDC provider which does not set an ID token `aud` claim. + +== SmallRye GraphQL + +The SmallRye GraphQL extension has replaced its OpenTracing integration with OpenTelemetry integration. When using OpenTracing, the extension will no longer produce any spans for GraphQL operations. The `quarkus.smallrye-graphql.tracing.enabled` configuration property was removed, and spans will automatically be produced by the SmallRye GraphQL extension when the OpenTelemetry extension is present. + +== Mockito + +The `mockito-inline` artifact is gone and, in most cases, you can just drop it from your `pom.xml` (and make sure you still have Mockito around). \ No newline at end of file diff --git a/migration/Migration-Guide-3.10.asciidoc b/migration/Migration-Guide-3.10.asciidoc new file mode 100644 index 0000000000..ddafe9f5e5 --- /dev/null +++ b/migration/Migration-Guide-3.10.asciidoc @@ -0,0 +1,143 @@ +:toc: + +[NOTE] +==== +We highly recommend the use of https://quarkus.io/guides/update-quarkus[`quarkus update`] to update to a new version of Quarkus. + +Items marked below with :gear: :white_check_mark: are automatically handled by https://quarkus.io/guides/update-quarkus[`quarkus update`]. +==== + +[id=flyway] +== Flyway 10 :gear: :white_check_mark: + +We updated Quarkus to Flyway 10. + +For some databases, the support that was previously part of the main artifact has been split to separate artifacts. + +For instance, the PostgreSQL support has been moved to `org.flywaydb:flyway-database-postgresql`. +If you are using Flyway with PostgreSQL, you need to add this dependency to your project. + +== OpenTelemetry + +* Support for traces when using the https://quarkus.io/guides/redis[`quarkus-redis-client`]. +* Rest clients span names will now include `operation` and `path`, instead of only the `operation` part. Example: "GET /hello" + +== Qute REST Integration + +The `io.quarkus.qute.TemplateInstance` is not registered as a non-blocking type anymore. Therefore, if a JAX-RS resource method returns `TemplateInstance`, then it will be considered _blocking_ by default. The `@io.smallrye.common.annotation.NonBlocking` annotation can be used to restore the previous behavior. + +NOTE: This change only affects applications using the Quarkus REST (formerly RESTEasy Reactive) via the `quarkus-rest` extension. + + +== Quarkus Messaging + +Starting from Quarkus 3.10, the execution mode for Quarkus Messaging extensions https://quarkus.io/blog/resteasy-reactive-smart-dispatch/#new-world-new-rules[_synchronous methods_] defaults to worker threads. +For example, the following processing method will now be called by default on the worker thread instead of Vert.x I/O thread: + +```java +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); +} +``` + +It is easy to revert this behaviour, using the `quarkus.messaging.blocking.signatures.execution.mode` property. +Possible values are `worker` (default), `event-loop` (previous behaviour) and `virtual-thread`. + +The execution mode can still be adjusted per method, using `@Blocking` and `@NonBlocking` annotations: + +```java +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 +} +``` + +[#packaging-config] +== Packaging configuration :gear: :white_check_mark: + +The following properties relating to packaging have been renamed or changed. If you use these properties in your configuration, they will still work, however a warning will be printed. + +[cols="1,1"] +|=== +| Original property name | Replaced with +| `quarkus.package.type` +| For JAR builds, use `quarkus.package.jar.type` with a valid JAR type (one of `fast-jar`, `uber-jar`, `mutable-jar`, or (deprecated) `legacy-jar`). + + For native builds, set `quarkus.native.enabled` to `true`. + + For native sources builds, also set `quarkus.native.sources-only` to `true`. + + JAR building can be disabled 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; 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` + +|=== + + +== OIDC `UserInfo` acquisition is enforced if `UserInfo` is injected + +Starting from Quarkus 3.9.0, `quarkus.oidc.authentication.user-info-required` property is now automatically set to `true` when `quarkus.oidc.UserInfo` is injected in the REST endpoint. + +It may cause OIDC tenant initialization failures if you use more than one OIDC tenant to secure the endpoint and some of these tenants do not support `UserInfo`. +In such cases, set a tenant specific `quarkus.oidc..authentication.user-info-required` property to `false`. \ No newline at end of file diff --git a/migration/Migration-Guide-3.11.asciidoc b/migration/Migration-Guide-3.11.asciidoc new file mode 100644 index 0000000000..63cba9bcd8 --- /dev/null +++ b/migration/Migration-Guide-3.11.asciidoc @@ -0,0 +1,39 @@ +:toc: + +[NOTE] +==== +We highly recommend the use of https://quarkus.io/guides/update-quarkus[`quarkus update`] to update to a new version of Quarkus. + +Items marked below with :gear: :white_check_mark: are automatically handled by https://quarkus.io/guides/update-quarkus[`quarkus update`]. +==== + +== Config + +Removed deprecated `ProfileManager#getActiveProfile` and `ProfileManager`. The `ProfileManager` could not handle multiple profiles, added in Quarkus 2.16. To retrieve the active profile, please use `io.quarkus.runtime.configuration.ConfigUtils#getProfiles`. The configuration name used to retrieve the Quarkus profile cannot be appropriately determined by a simple constant definition (as it was in `ProfileManager`); if you need it, please use `LaunchMode.current().getProfileKey()`. + +== JPA / Hibernate ORM + +=== Upgrade to Hibernate ORM 6.5 + +The Quarkus extensions for Hibernate ORM was upgraded to Hibernate ORM 6.5. + +Hibernate ORM 6.5 is largely backwards-compatible with Hibernate ORM 6.4, but a few checks have been tightened, so applications with incorrect configuration, mapping, or queries may now throw exceptions where they used to experience only warnings and malfunctions. + +See the https://github.com/hibernate/hibernate-orm/blob/6.5/migration-guide.adoc[Hibernate ORM 6.5 migration guide] for more details. + +[[elasticsearch-opensearch]] +== Elasticsearch/OpenSearch + +[[elasticsearch-opensearch-dev-services]] +=== Dev Services + +The Elasticsearch/OpenSearch Dev Services now default to starting: + +* Elasticsearch 8.13, instead of 8.12 previously +* OpenSearch 2.13, instead of 2.11 previously + +To force the use of a specific distribution (Elasticsearch vs. OpenSearch) or version, https://quarkus.io/guides/elasticsearch-dev-services#configuring-the-image[configure the container image explicitly]. + +== Webjar-locator extension renamed to Web-dependency-locator + +The Webjar locator has been enhanced to include https://mvnpm.org[mvnpm], and importmaps. Since this is now more that just webjars, we renamed to reflect this. Read more about the webjar locator https://quarkus.io/version/main/guides/web-dependency-locator[here] diff --git a/migration/Migration-Guide-3.12.asciidoc b/migration/Migration-Guide-3.12.asciidoc new file mode 100644 index 0000000000..951461e426 --- /dev/null +++ b/migration/Migration-Guide-3.12.asciidoc @@ -0,0 +1,104 @@ +:toc: + +== Hibernate ORM + +=== Database version now gets verified on startup even if relying on defaults + +The Hibernate ORM extension for Quarkus now verifies that the database version +it connects to at runtime is at least as high as the one configured at build time, +even when that configuration is not explicit +(i.e. when relying on the defaults that target Quarkus' minimum supported DB versions). + +This change was made to make application developers aware +they use a version of the database that is no longer considered as https://in.relation.to/2023/02/15/hibernate-orm-62-db-version-support/[supported by Hibernate ORM] or Quarkus: +in that case, Quarkus will refuse to start with an exception. + +This change should only affect applications relying on older database versions: + +- DB2 older than `10.5` +- Derby older than `10.15.2` +- Oracle Database older than `19.0` +- MariaDB older than `10.6` +- Microsoft SQL Server older than `13 (2016)` +- MySQL older than `8.0` +- PostgreSQL older than `12.0` + +See https://docs.jboss.org/hibernate/orm/6.5/dialect/dialect.html[here] for details. + +If the database cannot be upgraded to a supported version, it is still possible to use it, +although some features might not work. +To continue using an older, unsupported version of a database: + +* https://quarkus.io/guides/hibernate-orm#hibernate-dialect-supported-databases[Set the `db-version` explicitly] +* If necessary, https://quarkus.io/guides/hibernate-orm#hibernate-dialect-other-databases[set the dialect explicitly]. + In some cases, very old databases versions require using a legacy dialect found in the `hibernate-community-dialects` Maven artifact. See https://github.com/hibernate/hibernate-orm/blob/6.5/dialects.adoc#community-dialects[here] for more information. + +## Spring compatibility layer aligned with Spring Boot 3 + +### Key Changes in Spring Data JPA latest version + +**Introduction of New Interfaces:** + - With `spring-data-jpa 3.x`, two new interfaces, `ListCrudRepository` and `ListPagingAndSortingRepository`, were introduced. These interfaces return `List` types, unlike the existing `PagingAndSortingRepository` and `CrudRepository`, which return `Iterable`. + - The class hierarchy has been modified: `PagingAndSortingRepository` no longer extends `CrudRepository`. Instead, `JpaRepository` now extends both `CrudRepository` and `PagingAndSortingRepository`. + +### Refactoring of Spring Data REST extension: + - To accommodate these changes, the extension's hierarchy was restructured. Rather than maintaining different implementors, a single implementor now checks the repository type and implements the corresponding methods. + - All logic is consolidated in the `RepositoryMethodsImplementor`, which implements all repository methods based on the repository type. + - The `SpringDataRestProcessor` has been updated to include the new interfaces and now performs registration in a unified method (`registerRepositories`) instead of using two separate methods. + - Unification of PropertiesProvider Classes: these classes have been unified to incorporate the new methods from the `List***Repository` interfaces. + - Updates to `EntityClassHelper`: the `EntityClassHelper` has been relocated and now includes new methods used by `RepositoryMethodsImplementor` to detect the repository type for implementation. + - Modifications to Tests: the `Paged***Test` no longer checks methods inherited from `Crud**Repos`. A new test case, `CrudAndPagedResourceTest`, has been added for a repository extending both `Crud` and `Paged` repositories. + +Note: +The new `List****` methods are not specifically exposed via REST, as this is consistent with Spring's behavior. + +== OpenTelemetry + +=== Breaking Changes + +Legacy configuration properties that use the quarkus.opentelemetry.* namespace have been *removed* after almost one year of transition period. + +Please remember the changes done for Quarkus 3.0: + +All configurations have been updated from `quarkus.opentelemetry.*` → `quarkus.otel.*` to follow the OpenTelemetry Java https://opentelemetry.io/docs/languages/java/configuration/[autoconfigure] conventions. + +The sample configuration change requires additional work: `quarkus.opentelemetry.tracer.sampler` -> `quarkus.otel.traces.sampler`. + +If the sampler is parent based, there is no need to set, the now dropped property, `quarkus.opentelemetry.tracer.sampler.parent-based`. + +The values you need to set on `quarkus.opentelemetry.tracer.sampler` are now: + +|=== +|Old Sampler config value |New Sampler config value|New Sampler config value (Parent based) + +|`on` +|`always_on` +|`parentbased_always_on` + +|`off` +|`always_off` +|`parentbased_always_off` + +|`ratio` +|`traceidratio` +|`parentbased_traceidratio` +|=== + + +== Mailer with START TLS configuration + +In previous versions, configuring the mailer with START_TLS was ambiguous. In 3.12+, the configuration has been extended to avoid any ambiguity whether a TLS connection must be established to connect to the SMTP server or is later upgraded to TLS using the `START_TLS` command. + +You now need to explicitly configure `quarkus.mailer.tls` to `false` to make sure it does not establish a TLS connection to the SMTP server: + +``` +quarkus.mailer.from=... +quarkus.mailer.host=... +quarkus.mailer.port=... +qauarkus.mailer.mock=false + +quarkus.mailer.tls=false # Required to use START_TLS +quarkus.mailer.start-tls=REQUIRED +``` + +For named mailer, use `quarkus.mailer..tls=false`. diff --git a/migration/Migration-Guide-3.13.asciidoc b/migration/Migration-Guide-3.13.asciidoc new file mode 100644 index 0000000000..441e4e274c --- /dev/null +++ b/migration/Migration-Guide-3.13.asciidoc @@ -0,0 +1,120 @@ +:toc: + +[NOTE] +==== +We highly recommend the use of https://quarkus.io/guides/update-quarkus[`quarkus update`] to update to a new version of Quarkus. + +Items marked below with :gear: :white_check_mark: are automatically handled by https://quarkus.io/guides/update-quarkus[`quarkus update`]. +==== + +== Redis Client + +=== Fixed parameter ordering in JSON.MGET + +The `JsonCommands.jsonMget()` method (and similar methods like `ReactiveJsonCommands.jsonMget()`) declare parameters in the following order: + +- `String path` +- `K\... keys` + +This is opposite to the Redis JSON.MGET command, which accepts keys first and path last. + +The implementation of the `jsonMget()` method used to follow the Redis order, despite its own declaration. +That is, the `path` had to be _last_, even though it should be first. + +This is now fixed. +All users of this method have to check and fix the call sites. + +== OpenTelemetry + +Many changes on this release, affecting documentation, Metrics support and breaking changes due to the new semantic conventions for HTTP. + +=== OpenTelemetry metrics support + +Added with experimental status, please set `quarkus.otel.metrics.enabled=true` to enable it at build time. + +Now you can create OpenTelemetry Metrics by following the https://quarkus.io/version/main/guides/opentelemetry-metrics[Metrics Guide]. + +There are no automatic OpenTelemetry metrics instrumentation in Quarkus, for now. Metrics in Quarkus are implemented by the Micrometer extension. We plan to provide, in the future, a bridge for those metrics to be available in OpenTelemetry as well. + +=== Documentation updates + +The old OpenTelemetry guide has been split into this https://quarkus.io/version/main/guides/opentelemetry[generic guide], the OpenTelemetry https://quarkus.io/version/main/guides/opentelemetry-tracing[Tracing Guide] and the new OpenTelemetry https://quarkus.io/version/main/guides/opentelemetry-metrics[Metrics Guide] has been created. + +=== Breaking Changes + +* Upgrade to OpenTelemetry SDK 1.39.0 and OpenTelemetry instrumentation 2.5.0. +We haven't upgraded OpenTelemetry for a while to allow a transition period from the old, deprecated HTTP semantic conventions, as announced in this https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.9#semantic-convention-changes[wiki migration guide] for Quarkus 3.9 and the https://groups.google.com/g/quarkus-dev/c/MsU_KWwKgoo/m/klx-yLwDAQAJ[Dev mailing list]. +The transition period has now ended with the upgrade of the OpenTelemetry SDK to 1.39.0 and OpenTelemetry instrumentation to 2.5.0. These versions require the new semantic conventions for HTTP. The full https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/migration-guide.md#summary-of-changes[list of changes]. + +* `quarkus.otel.semconv-stability.opt-in` system property was removed because users cannot opt-in anymore; + +* DB Span names have changed in the case of table creation; + +* Deprecated annotation for `io.opentelemetry.extension.annotations.WithSpan` has been removed. Please use the new `io.opentelemetry.instrumentation.annotations.WithSpan`, as previously announced. + +== Grafana LGTM (all-in-one) Observability Dev Service + +The extension now detects which extensions (Otel, Micrometer OTLP registry) are being used and sets their properties accordingly. +No need to configure the `application.properties` file for this anymore. The https://quarkus.io/version/main/guides/observability-devservices-lgtm[documentation] was also updated. + +*Breaking Change* + +The following properties are removed because they are not needed anymore: + +* `quarkus.otel-collector.url` +* `quarkus.grafana.url` + + +== Hibernate ORM + +=== Auto-flush optimization + +Starting with Quarkus 3.13, before executing a JPQL/HQL or native query, Hibernate ORM will only flush pending changes to the database if it detects that the query results may be impacted by these changes. + +This optimization was https://docs.jboss.org/hibernate/orm/6.5/userguide/html_single/Hibernate_User_Guide.html#_auto_flush_on_jpqlhql_query[available for a long time in Hibernate ORM], but was https://github.com/quarkusio/quarkus/pull/14305/files#diff-3c3d11a887a43713907202d00e1d26f8d664c00c408de92e21904f76f10d7b84R35[disabled by mistake] in Quarkus 1.13, causing https://github.com/quarkusio/quarkus/issues/41115[performance issues] ever since. + +Most applications should only experience performance improvements (better batching), but some might run into problems: + +* if using native queries, which require specific care; see https://docs.jboss.org/hibernate/orm/6.5/userguide/html_single/Hibernate_User_Guide.html#_auto_flush_on_native_sql_query[this section of the Hibernate ORM documentation]. +* if Hibernate ORM somehow fails to automatically detect that pending changes impact a JPQL/HQL query; please report any such problem with a reproducer https://github.com/hibernate/hibernate-test-case-templates/blob/main/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/QuarkusLikeORMUnitTestCase.java[based on this template]. + +== +++@QuarkusTestResource replaced by @WithTestResource+++ + +While we initially planned replacing `@QuarkusTestResource` with `@WithTestResource`, some severe issues led us to reconsider this plan. + +Thus, while you will see that `@QuarkusTestResource` has been deprecated in 3.13, we will undeprecate it in 3.14 so please keep using it and don't move to `@WithTestResource`. + +You can have a look at https://groups.google.com/g/quarkus-dev/c/rS8-WN6b7XQ for more details. + +== Quarkus CLI + +The default behaviour of calling `quarkus config` is to display the help text for all subcommands instead of calling `set`. + +=== `config set` + +- The Options `name` and `value` are now Parameters. For instance, to set the configuration `foo=bar`, the previous command was `quarkus config set --name=foo --value=bar`. The new command is `quarkus config set foo bar`. +- No longer removes the configuration if it exists from `application.properties` when the `value` parameter is omitted from the command. Now, there is a specific subcommand to remove configuration `quarkus config remove NAME` + +=== `config encrypt` + +- The Option `secret` is now a Parameter. For instance, to encrypt a value, the previous command was `quarkus config encrypt --secret=12345678`. The new command is `quarkus config encrypt 1234578`. + +== Dev Services startup detection change + +The way we check if Dev Services should be started has changed. +We used to check if a property was defined to know if we should start the Dev Services or not without expanding it but it was causing issues if in the end the property was empty when expanded. +We now check that the expanded property is empty, which might lead to the Dev Services being started while they weren't in some cases. + +For instance, people using the `quarkus-test-oidc-server` component to mock the OIDC server will have to adjust their configuration due to https://github.com/quarkusio/quarkus/pull/41326[a change in how we check the presence of configuration property in the Dev Services startup code]. +Note that this particular example that is quite common is handled by `quarkus update` :gear: :white_check_mark:. + +If you have this in your `application.properties`: + +``` +%test.quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus/ +``` + +You should change it to this: +``` +%test.quarkus.oidc.auth-server-url=${keycloak.url:replaced-by-test-resource}/realms/quarkus/ +``` \ No newline at end of file diff --git a/migration/Migration-Guide-3.14.asciidoc b/migration/Migration-Guide-3.14.asciidoc new file mode 100644 index 0000000000..6761c203e5 --- /dev/null +++ b/migration/Migration-Guide-3.14.asciidoc @@ -0,0 +1,187 @@ +:toc: + +[NOTE] +==== +We highly recommend the use of https://quarkus.io/guides/update-quarkus[`quarkus update`] to update to a new version of Quarkus. + +Items marked below with :gear: :white_check_mark: are automatically handled by https://quarkus.io/guides/update-quarkus[`quarkus update`]. +==== + +== JPA / Hibernate ORM + +=== Upgrade to Hibernate ORM 6.6 + +The Quarkus extensions for Hibernate ORM was upgraded to Hibernate ORM 6.6. + +Hibernate ORM 6.6 is largely backwards-compatible with Hibernate ORM 6.5, +but a few checks have been tightened, so applications with incorrect configuration, mapping, or queries +may now throw exceptions where they used to experience only warnings and malfunctions. In particular: + +* https://docs.jboss.org/hibernate/orm/6.6/migration-guide/migration-guide.html#merge-versioned-entity-when-row-is-deleted[Merging detects invalid creation attempts]: +passing to `merge` an entity with a `@GeneratedValue` identifier or a `@Version` property set to a non-null value +will now fail, whereas it used to (incorrectly) create the entity in database. +* https://docs.jboss.org/hibernate/orm/6.6/migration-guide/migration-guide.html#explicit-validation-of-annotated-class-types[Applying both `@MappedSuperclass` and `@Embeddable` on the same type is not longer allowed]. + +Some features are also now enabled by default to avoid unexpected -- and arguably error-prone -- behavior: + +* https://docs.jboss.org/hibernate/orm/6.6/migration-guide/migration-guide.html#discriminator-based-embeddable-inheritance[Embeddables with `@Embeddable` annotated subtypes will now use discriminator-based inheritance by default]. + +Finally, behavior was altered in some cases to comply with the JPA specification: + +* https://docs.jboss.org/hibernate/orm/6.6/migration-guide/migration-guide.html#criteria-jakartapersistencecriteriaexpressionasclass[`jakarta.persistence.criteria.Expression#as(Class)` is now an unchecked cast]: use `org.hibernate.query.criteria.JpaExpression#cast(Class)` to perform a checked cast. + +See the https://docs.jboss.org/hibernate/orm/6.6/migration-guide/migration-guide.html[Hibernate ORM 6.6 migration guide] for more details. + +== SmallRye Health + +Some configuration properties were incorrectly under the `quarkus.health` config root whereas they should have been under the `quarkus.smallrye-health` config root to be consistent. + +This includes: + +- `quarkus.health.extensions.enabled` -> `quarkus.smallrye-health.extensions.enabled` +- `quarkus.health.openapi.included` -> `quarkus.smallrye-health.openapi.included` + +The old properties have been deprecated and will be removed at some point in the future. + +== MongoDB + +The MongoDB client has been upgraded from 4.11.1 to 5.1.3. + +== Dev Services + +Several Dev Services default images have been updated: + +- PostgreSQL from 14 to 16 +- MySQL from 8.0 to 8.4 +- MongoDB from 4.4 to 7.0 +- Elasticsearch from 8.13 to 8.15 +- OpenSearch from 2.13 to 2.16 + +NOTE: You can configure Quarkus explicitly to use a specific image for each Dev Service, e.g. see https://quarkus.io/guides/elasticsearch-dev-services#configuring-the-image[here for Elasticsearch/OpenSearch]. + +== For extension developers + +This paragraph only concerns people developing their own Quarkus extensions. + +=== Getting your application to compile + +The extension annotation processor that is used to generate some files required for the Quarkus runtime and the configuration documentation has been redeveloped from scratch. +It is a lot more flexible but comes with some new constraints: + +- You cannot mix configuration using the legacy `@ConfigRoot` approach (i.e. without a corresponding `@ConfigMapping` annotation) and the new `@ConfigMapping` approach in the same module. This shouldn't be too much of a problem. +- If you use the new `@ConfigMapping` approach, you don't need to configure anything. The change should be transparent for you. +- If you use the legacy `@ConfigRoot` approach (i.e. without a corresponding `@ConfigMapping` annotation), you need to inform the annotation processor of it: ++ +[source,xml] +---- + + org.apache.maven.plugins + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + -AlegacyConfigRoot=true + + + +---- ++ +The important part is the added `compilerArgs` `-AlegacyConfigRoot=true`. ++ +Note that this will result in a warning when compiling the test classes (given you don't have config annotations in your test classes, the annotation processor will not be triggered and you will get a warning telling you the `legacyConfigRoot` parameter is unused). +To alleviate this issue, it is recommended to only enable the annotation processor for the `default-compile` execution (which compiles the main classes): ++ +[source,xml] +---- + + maven-compiler-plugin + + + default-compile + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + -AlegacyConfigRoot=true + + + + + +---- + +=== Publishing the config documentation + +The config documentation used to be generated in the root `target/generated/config` directory by the extension annotation processor itself. + +This is not the case anymore: the extension annotation processor builds a model that is in each module, and we have a Maven plugin that assembles the model and generate the Asciidoc output. + +In your typical Quarkiverse extension, you would have to apply the following changes: + +- Set the version of the `quarkus-config-doc-maven-plugin` in the root POM `` section +- Drop the copy of the generated doc in `docs/pom.xml` +- Set up the `quarkus-config-doc-maven-plugin` in `docs/pom.xml` + +A typical diff would look like the following: + +[source,diff] +---- +diff --git a/docs/pom.xml b/docs/pom.xml +index 71be73f..5022bf4 100644 +--- a/docs/pom.xml ++++ b/docs/pom.xml +@@ -56,6 +56,14 @@ + + + ++ ++ io.quarkus ++ quarkus-config-doc-maven-plugin ++ true ++ ++ ${project.basedir}/modules/ROOT/pages/includes/ ++ ++ + + maven-resources-plugin + +@@ -68,11 +76,6 @@ + + ${project.basedir}/modules/ROOT/pages/includes/ + +- +- ${project.basedir}/../target/asciidoc/generated/config/ +- quarkus-github-app.adoc +- false +- + + ${project.basedir}/templates/includes + attributes.adoc +diff --git a/pom.xml b/pom.xml +index c87d42b..10cbacd 100644 +--- a/pom.xml ++++ b/pom.xml +@@ -98,6 +98,11 @@ + quarkus-maven-plugin + ${quarkus.version} + ++ ++ io.quarkus ++ quarkus-config-doc-maven-plugin ++ ${quarkus.version} ++ + + org.apache.maven.plugins + maven-compiler-plugin +---- \ No newline at end of file diff --git a/migration/Migration-Guide-3.16.asciidoc b/migration/Migration-Guide-3.16.asciidoc new file mode 100644 index 0000000000..a9efc46eb8 --- /dev/null +++ b/migration/Migration-Guide-3.16.asciidoc @@ -0,0 +1,60 @@ +:toc: + +[NOTE] +==== +We highly recommend the use of https://quarkus.io/guides/update-quarkus[`quarkus update`] to update to a new version of Quarkus. + +Items marked below with :gear: :white_check_mark: are automatically handled by https://quarkus.io/guides/update-quarkus[`quarkus update`]. +==== + +== Micrometer + +Micrometer has been upgraded from 1.12.5 to 1.13.3. +One of the changes is the use of Prometheus client v1.x, however, Quarkus will keep using the old deprecated v0.x client for longer. + +This requires no changes from users. + +However, is for some reason you are using the old dependency in some tests: +```xml + + io.micrometer + micrometer-registry-prometheus + +``` +the new one is: +```xml + + io.micrometer + micrometer-registry-prometheus-simpleclient + +``` +*MeterFilters* + +Beware of using bean implementations of `MeterFilter` to return dynamic content like: +```java +@Singleton +public class MeterFilterProducer { + + @Inject + RequestScopedHeader requestScopedHeader; + + @Produces + @Singleton + public MeterFilter addTags() { + return new MeterFilter() { + @Override + public Meter.Id map(Meter.Id id) { + if (id.getName().startsWith("something")) { + return id.withTag(Tag.of("my-header-tag", requestScopedHeader.getHeaderValue())); + } else { + return id; + } + } + }; + } +} +``` +It is supposed the returned content to be constant and not depend on runtime. +There are meter caching changes on Micrometer 1.13+ that will break metrics depending on this code. + +In Quarkus, the recommended way to add tags containing data from HTTP requests is using the https://quarkus.io/guides/telemetry-micrometer#use-httpservermetricstagscontributor-for-server-http-requests[HttpServerMetricsTagsContributor]. \ No newline at end of file diff --git a/migration/Migration-Guide-3.2.asciidoc b/migration/Migration-Guide-3.2.asciidoc new file mode 100644 index 0000000000..a1694702e1 --- /dev/null +++ b/migration/Migration-Guide-3.2.asciidoc @@ -0,0 +1,118 @@ +:toc: + +== `@InjectMock` + +`io.quarkus.test.junit.mockito.InjectMock` has been deprecated in favor of `io.quarkus.test.InjectMock`. + +== Native Compilation - Native executables and .so files + +Due to changes made to GraalVM/Mandrel, if you are using an extension that is relying on `.so` files (such as the AWT extension), you need to add these `.so` files to the native container similarly to: + +[source,docker] +---- +... +# Copy of the .so files to the container +COPY --chown=1001:root target/*.so /work/ +COPY --chown=1001:root target/*-runner /work/application +... +---- + +== Native Compilation - Work around missing CPU features + +When building on recent machines and running your native executable on older machines, you may see the following failure when starting the application: + +[source] +---- +The current machine does not support all of the following CPU features that are required by the image: [CX8, CMOV, FXSR, MMX, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT, LZCNT, AVX, AVX2, BMI1, BMI2, FMA]. +Please rebuild the executable with an appropriate setting of the -march option. +---- + +This error message means that the native compilation used more advanced instruction sets not supported by the CPU running the application. +To work around that issue, add the following line to the `application.properties`: + +[source, properties] +---- +quarkus.native.additional-build-args=-march=compatibility +---- + +Then, rebuild your native executable. +This setting forces the native compilation to use an older instruction set, increasing the chance of compatibility. + +To explicitly define the target architecture, run `native-image -march=list` to get the supported configurations and then set `-march` to one of them, e.g., `quarkus.native.additional-build-args=-march=x86-64-v4`. +If you are targeting an AMD64 host, `-march=x86-64-v2` would work in most cases. + +NOTE: The `march` parameter is only available on GraalVM 23+. + +== Transaction manager (Narayana) + +The configuration property `quarkus.transaction-manager.object-store-directory` has been renamed to `quarkus.transaction-manager.object-store.directory`. + +== Kubernetes + +=== Improve the logic to generate TLS-based container ports + +At the moment, the Kubernetes extension is always adding a container port called `https` to the generated Deployment resources. This approach is problematic because the port won't work unless SSL is configured. + +After 3.2, the container port `https` will not be added to the generated Deployment resources by default, unless: +- Either users explicitly provide some of the `quarkus.http.ssl.*` properties at build time. +- Or users add this property `quarkus.kubernetes.ports.https.tls=true` at build time. + +More information about these changes in https://github.com/quarkusio/quarkus/issues/33307[here]. + +=== Management interface port is not bound as a Service any longer + +When the management port is enabled (see more information https://quarkus.io/guides/management-interface-reference[here]), the Kubernetes extension will not generate the Kubernetes Service that binds the management port by default for security reasons. + +Still, if you want to expose it via Service and Ingress resources, you can add the following properties: + +``` +quarkus.kubernetes.ingress.expose=true +quarkus.kubernetes.ingress.target-port=management +``` + +For OpenShift, you would need: + +``` +quarkus.openshift.route.expose=true +quarkus.openshift.route.target-port=management +``` + +And now, a new Kubernetes Service will be generated to bind the Management interface port. + +== Hibernate Search + +=== Defaults for projectable/sortable on geo-point fields + +NOTE: The following applies to Quarkus 3.2.3+ only, as Quarkus 3.2.0, 3.2.1, 3.2.2 were still using Hibernate Search 6.1. + +Hibernate Search 6.2 changed how defaults are handled for geo-point fields. + +If your Hibernate Search mapping includes geo-point fields that are using the default value for the `projectable` option, +and are using either the default value or `Sortable.NO` for the `sortable` option, +Elasticsearch schema validation will fail on startup because of missing docvalues on those fields. + +To address that, either: + +* Revert to the previous defaults by adding `projectable = Projectable.NO` to the mapping annotation of relevant geo-point fields. +* Or recreate your Elasticsearch indexes and reindex your database. The easiest way to do so is to use https://docs.jboss.org/hibernate/search/6.2/reference/en-US/html_single/#indexing-massindexer[the `MassIndexer`] with https://docs.jboss.org/hibernate/search/6.2/reference/en-US/html_single/#indexing-massindexer-parameters-drop-and-create-schema[`dropAndCreateSchemaOnStart(true)`]. + +See also https://docs.jboss.org/hibernate/search/6.2/migration/html_single/#data-format + +=== Different DB schema for outbox-polling + +NOTE: The following applies to Quarkus 3.2.3+ only, as Quarkus 3.2.0, 3.2.1, 3.2.2 were still using Hibernate Search 6.1. + +If you use the `quarkus-hibernate-search-orm-outbox-polling` extension, +be aware that the database schema for the tables used by that extension changed. + +See https://docs.jboss.org/hibernate/search/6.2/migration/html_single/#data-format +for help on how to migrate to the new schema. + +=== Deprecated/renamed configuration properties + +NOTE: The following applies to Quarkus 3.2.3+ only, as Quarkus 3.2.0, 3.2.1, 3.2.2 were still using Hibernate Search 6.1. + +* `quarkus.hibernate-search-orm.automatic-indexing.synchronization.strategy` is now deprecated in favor of `quarkus.hibernate-search-orm.indexing.plan.synchronization.strategy`. +* `quarkus.hibernate-search-orm.automatic-indexing.enable-dirty-check` is now deprecated with no alternative to replace it. After its removal in a future version, a dirty check will always be performed when considering whether to trigger reindexing. + +See also https://docs.jboss.org/hibernate/search/6.2/migration/html_single/#configuration \ No newline at end of file diff --git a/migration/Migration-Guide-3.3.asciidoc b/migration/Migration-Guide-3.3.asciidoc new file mode 100644 index 0000000000..8013a8a0c8 --- /dev/null +++ b/migration/Migration-Guide-3.3.asciidoc @@ -0,0 +1,97 @@ +:toc: + +== Elasticsearch + +=== Dev Services + +The Elasticsearch Dev Services now default to starting Elasticsearch 8, instead of 7.17 previously. + +To use another version, https://quarkus.io/guides/elasticsearch-dev-services#configuring-the-image[configure another container image explicitly]. + +=== High-Level Client + +The extension for the Elasticsearch High-Level Client was deprecated in Quarkus 3.0 because the client had been deprecated by Elastic and had licensing issues. + +This extension has now been removed completely. + +You should use the Elasticsearch Java Client instead. See https://quarkus.io/guides/elasticsearch[the Elasticsearch client guide] for more information. + +== Flyway + +=== Additional dependency required for Oracle users + +Quarkus 3.3.x upgrades to https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html[Flyway 9.20.0], which extracts the Oracle DB code to a separate https://documentation.red-gate.com/fd/oracle-184127602.html[dependency]. See the https://quarkus.io/guides/flyway[Flyway extension documentation] for more information. + +== Hibernate Search + +=== Defaults for projectable/sortable on geo-point fields + +Hibernate Search 6.2 changed how defaults are handled for geo-point fields. + +If your Hibernate Search mapping includes geo-point fields that are using the default value for the `projectable` option, +and are using either the default value or `Sortable.NO` for the `sortable` option, +Elasticsearch schema validation will fail on startup because of missing docvalues on those fields. + +To address that, either: + +* Revert to the previous defaults by adding `projectable = Projectable.NO` to the mapping annotation of relevant geo-point fields. +* Or recreate your Elasticsearch indexes and reindex your database. The easiest way to do so is to use https://docs.jboss.org/hibernate/search/6.2/reference/en-US/html_single/#indexing-massindexer[the `MassIndexer`] with https://docs.jboss.org/hibernate/search/6.2/reference/en-US/html_single/#indexing-massindexer-parameters-drop-and-create-schema[`dropAndCreateSchemaOnStart(true)`]. + +See also https://docs.jboss.org/hibernate/search/6.2/migration/html_single/#data-format + +=== Different DB schema for outbox-polling + +If you use the `quarkus-hibernate-search-orm-outbox-polling` extension, +be aware that the database schema for the tables used by that extension changed. + +See https://docs.jboss.org/hibernate/search/6.2/migration/html_single/#data-format +for help on how to migrate to the new schema. + +=== Deprecated/renamed configuration properties + +* `quarkus.hibernate-search-orm.automatic-indexing.synchronization.strategy` is now deprecated in favor of `quarkus.hibernate-search-orm.indexing.plan.synchronization.strategy`. +* `quarkus.hibernate-search-orm.automatic-indexing.enable-dirty-check` is now deprecated with no alternative to replace it. After its removal in a future version, a dirty check will always be performed when considering whether to trigger reindexing. + +See also https://docs.jboss.org/hibernate/search/6.2/migration/html_single/#configuration + +== GraalVM + +We are now relying consistently on the `org.graalvm.sdk:graal-sdk` artifact (we previously used the non-API `svm` artifact). + +The dependencies to this artifact are marked as `provided` in Quarkus so they are not transitive: if you want to include GraalVM substitutions in your applications, please add it as a dependency yourself from now on. + +It is part of the BOM so you don't have to define the version. + +== OpenTelemetry (OTel) + +This version brings extensive improvements to the `quarkus-opentelemetry' extension. Please check the full list of changes of the release notes. In here we mention noteworthy new features and behaviours that might have changed. + +* OTel 1.28 is now supported. +* The default OTel exporter has been replaced by a Quarkus implementation on top of Vert.x. This allows us not to depend on the OkHttp library. The exporter continues to be automatically wired with CDI, that's why the `quarkus.otel.traces.exporter` property defaults to `cdi`. +* The new Quarkus Vert.x exporter now supports `grpc` (default) and `http/protobuf`. Please change the protocol with this property: `quarkus.otel.exporter.otlp.traces.protocol` +* The Quarkus OTel exporter will now have TLS support. +* When setting `quarkus.tls.trust-all=true`, it will also disable all SSL verifications on the Quarkus OTel exporter. +* We added a way to customise the propagation header. This can be achieved by implementing the `TextMapPropagatorCustomizer` interface. This can be used, as an example, to restrict propagation of OpenTelemetry trace headers and prevent potentially sensitive data to be sent to third party systems. +* By setting `quarkus.otel.traces.eusp.enabled=true` you can add information about the user related to each span. The user’s ID and roles will be added to the span attributes, if available. +* We now properly report the `http.route` attribute. +* Swagger UI endpoints will not be tracked anymore. +* Spans of Failed requests will now contain stack traces. +* OTel instantiation has been improved to prevent racing condition at startup. + +== Micrometer + +* Micrometer will now provide Netty allocation metrics if the related classes are present in the classpath, which is the usual case. +* Customise emitted tags by implementing `HttpServerMetricsTagsContributor` and emitted metrics by implementing `MeterRegistryCustomizer`. +* Auth failures will now populate the metrics URI tag. + +== Keycloak Authorization + +`org.keycloak:keycloak-adapter-core` dependency has been removed from the `quarkus-keycloak-authorization` extension with the update to `Keycloak 22.0.0` because it is no longer relevant to the functionality of `quarkus-keycloak-authorization`, with Keycloak Java adapters code planned to be removed from Keycloak in the future as well. + +If necessary, please add this dependency to your application's pom: +``` + + org.keycloak + keycloak-adapter-core + +``` \ No newline at end of file diff --git a/migration/Migration-Guide-3.4.asciidoc b/migration/Migration-Guide-3.4.asciidoc new file mode 100644 index 0000000000..2e28c0c531 --- /dev/null +++ b/migration/Migration-Guide-3.4.asciidoc @@ -0,0 +1,49 @@ +:toc: + +== Vert.x HTTP + +=== Configuration + +The Vert.x HTTP configuration was migrated to the new `ConfigMapping` infrastructure. +The main visible change is that the configuration classes are now interfaces. + +If you were consuming them in an extension to get the configuration property values (for instance by injecting `io.quarkus.vertx.http.runtime.HttpConfiguration`), you will have to adjust your code accordingly to use the interface methods (instead of the class fields). +Adding `()` at the end of each consumed field should be all that's needed in most cases. + +== Flyway + +The Flyway extension has seen significant changes in 3.3 and some of these changes introduced some regressions in corner cases, typically when you had several datasources, one of which is not supported by Flyway. + +It is now possible to entirely disable the automatic setup of the Flyway extension by setting quarkus.flyway.enabled=false. + +You can also make Flyway inactive for a specific datasource by setting quarkus.flyway.active=false for the default datasource or quarkus.flyway."datasource name".active=false for a named datasource. + +== Elasticsearch + +=== Dev Services + +The Elasticsearch Dev Services now default to starting Elasticsearch 8.9, instead of 8.8 previously. + +Also, Elasticsearch Dev Services will now automatically start OpenSearch instead of Elasticsearch when they detect that a Quarkus extension expects OpenSearch. Currently only the Hibernate Search extension takes advantage of this feature. + +To force the use of a specific distribution (Elasticsearch vs. OpenSearch) or version, https://quarkus.io/version/3.4/guides/elasticsearch-dev-services#configuring-the-image[configure the container image explicitly]. + +== SmallRye GraphQL + +=== Directives + +Previously, annotation-based GraphQL directives got applied on any element of the GraphQL schema, regardless of whether that directive was actually declared to be applicable to that element type. This has now been fixed and the directive annotation's `on` parameter is used for determining allowed placement for directives. This change might potentially break some applications that were written incorrectly but were working by accident, so if you use annotation-based GraphQL directives, we recommend verifying that their usages correspond to the directive's declaration. + +== Component testing + +=== Programmatic registration + +The `QuarkusComponentTestExtension` is now immutable. +As a result, if you register the `QuarkusComponentTestExtension` programmatically then the static field is initialized with with the `QuarkusComponentTestExtension(Class...)` simplified constructor or with the convenient `QuarkusComponentTestExtension.builder()`. + +=== Lifecycle + +The test instance lifecycle determines the test phase in which the CDI container is started/stopped. +If the test instance lifecycle is `Lifecycle#PER_METHOD` (default) then the container is started during the `before each` test phase and stopped during the `after each` test phase. +However, if the test instance lifecycle is `Lifecycle#PER_CLASS` then the container is started during the `before all` test phase and stopped during the `after all` test phase. +In previous versions, the container was always started during the `before all` test phase and stopped during the `after all` test phase. \ No newline at end of file diff --git a/migration/Migration-Guide-3.5.asciidoc b/migration/Migration-Guide-3.5.asciidoc new file mode 100644 index 0000000000..524a078f8c --- /dev/null +++ b/migration/Migration-Guide-3.5.asciidoc @@ -0,0 +1,53 @@ +:toc: + +== Config + +=== Kubernetes Environment Variables + +Environment variables set for Kubernetes-based extensions require configuration names to use upper case names separated by underscores as documented in the https://quarkus.io/guides/config-reference#environment-variables[Configuration Reference]. In previous releases, it was possible to use lowercase dotted names. This was accidental and never intended to work this way. + +=== Config property values injected during static intialization phase + +Quarkus collects the config property values injected in CDI beans during the static intialization phase. +The collected values are then compared with their runtime initialization counterparts and if a mismatch is detected the application startup fails. + +How can it happen? +For example, let's have a CDI bean `org.acme.MyBean`. +`MyBean` injects a `@ConfigProperty` of name `foo` and is initialized during the native build. +The config property does not exist during the native build and so the default value `bar` is used. +But later, when the application is started the property is defined with a system property: `-Dfoo=baz`. +This would lead to inconsistent state and unexpected behavior. +Therefore, Quarkus would fail in this situation by default. + +You can annotate an injected field/parameter with `@io.quarkus.runtime.annotations.StaticInitSafe` to mark the injected configuration object as safe to be initialized during the static intialization phase. + +== Qute + +A user tag is now executed as an _isolated_ template by default, i.e. without access to the context of the template that calls the tag. +If you need to change the default behavior and disable the isolation, just add `_isolated=false` or `_unisolated` argument to the call site. For example `{#itemDetail item showImage=true _isolated=false /}` or `{#itemDetail item showImage=true _unisolated /}`. See also https://github.com/quarkusio/quarkus/discussions/22285[the discussion] for more details. + +`io.quarkus.qute.ResultNode` is now an abstract class (it was an interface). In general, the `ResultNode` should not be implemented by users but it's part of the public API. + +The Qute API is built on top of `java.util.concurrent.CompletionStage`. Up to now, any implementation could be used in the API. Since Quarkus 3.5 only the `java.util.concurrent.CompletableFuture` and the internal `io.quarkus.qute.CompletedStage` are supported by default. The behavior can be changed with the system property `-Dquarkus.qute.unrestricted-completion-stage-support=true`. + +== Dev Services + +=== Microsoft SQL Server + +The Microsoft SQL Server Dev Services have been upgraded to `2022-latest` (and `azure-sql-edge:latest` for Mx Macs). + +You will need to adjust your `container-license-acceptance.txt` file accordingly. + +== OpenTelemetry + +=== `@AddingSpanAttributes` now available + +Annotating a method in any CDI aware bean with the `io.opentelemetry.instrumentation.annotations.AddingSpanAttributes` will not create a new span but will add annotated method parameters to attributes in the current span. + +If a method is annotated by mistake with `@AddingSpanAttributes` and `@WithSpan` annotations, the `@WithSpan` annotation will take precedence. + +== OptaPlanner + +The OptaPlanner extensions have been removed from the Quarkus Platform as they were not compatible anymore with the latest Quarkus versions. + +We recommend you to migrate to the https://timefold.ai/[Timefold] Quarkus extensions (available in the tooling and on https://code.quarkus.io/). Timefold is a fork of OptaPlanner. \ No newline at end of file diff --git a/migration/Migration-Guide-3.6.asciidoc b/migration/Migration-Guide-3.6.asciidoc new file mode 100644 index 0000000000..61b0ca45b0 --- /dev/null +++ b/migration/Migration-Guide-3.6.asciidoc @@ -0,0 +1,40 @@ +:toc: + +[NOTE] +==== +We highly recommend the use of https://quarkus.io/guides/update-quarkus[`quarkus update`] to update to a new version of Quarkus. + +Items marked below with :gear: :white_check_mark: are automatically handled by https://quarkus.io/guides/update-quarkus[`quarkus update`]. +==== + +== Jaeger and SmallRye OpenTracing extensions retired :gear: :white_check_mark: + +After having been deprecated for a long while, the Jaeger and SmallRye OpenTracing extensions have been retired from the Quarkus Platform. + +It is recommended to migrate your applications to OpenTelemetry and a https://quarkus.io/version/main/guides/telemetry-opentracing-to-otel-tutorial[tutorial is available]. + +The code of the extensions have been moved to the Quarkiverse and can be consumed from there from now on (relocations have been put in place to avoid breaking your builds). +If you want these extensions to continue working in the future, it is recommended to be involved in their development. + +These extensions are not in the Quarkus Platform BOM anymore and you need to define the version yourself in your build file, together with moving to the new groupId: + +|=== +| Component | New groupId | Current version | Repository | + +| Jaeger | `io.quarkiverse.jaeger` | `1.0.0` | https://github.com/quarkiverse/quarkus-jaeger | +| SmallRye OpenTracing | `io.quarkiverse.opentracing` | `1.0.0` | https://github.com/quarkiverse/quarkus-smallrye-opentracing | +|=== + +== Kafka extension Strimzi Oauth Support known issue + +With version 3.6 the quarkus-bom version of the `io.strimzi:strimzi-kafka-oauth` dependency is updated to `0.14.0`. +A https://github.com/strimzi/strimzi-kafka-oauth/issues/209[known issue] in this version causes native build failure with the error `" Error: Substitution target for io.smallrye.reactive.kafka.graal.Target_com_jayway_jsonpath_internal_DefaultsImpl is not loaded.`. + +The workaround until the upstream issue is resolved is to add the `io.strimzi:kafka-oauth-common` dependency to the classpath of the Quarkus project. + +== Quarkus SmallRye JWT and Reactive Routes + +Quarkus SmallRye JWT used to bring the `quarkus-reactive-routes` extension prior to 3.6. +That is not the case anymore in 3.6. + +So if you relied on Quarkus SmallRye JWT to bring the `quarkus-reactive-routes` extension, add a dependency to `quarkus-reactive-routes` in your build file. diff --git a/migration/Migration-Guide-3.7.asciidoc b/migration/Migration-Guide-3.7.asciidoc new file mode 100644 index 0000000000..083b09ebd6 --- /dev/null +++ b/migration/Migration-Guide-3.7.asciidoc @@ -0,0 +1,275 @@ +:toc: + +[NOTE] +==== +We highly recommend the use of https://quarkus.io/guides/update-quarkus[`quarkus update`] to update to a new version of Quarkus. + +Items marked below with :gear: :white_check_mark: are automatically handled by https://quarkus.io/guides/update-quarkus[`quarkus update`]. +==== + +[#java17] +== Java 17 :gear: :white_check_mark: + +Starting with Quarkus 3.7, Java 17 is the minimum version you need to use to build and run Quarkus applications. + +You can of course also use Java 21. + +For more information about this change, see the https://quarkus.io/blog/java-17/[this blog post]. + +[#restclient] +== REST Client :gear: :white_check_mark: + +As part of the renaming of the RESTEasy Reactive extensions that will be spread across several releases, we renamed the `quarkus-rest-client*` extensions (client extensions for RESTEasy Classic) to `quarkus-resteasy-client*`, which makes it clearer that it is the client counterpart of `quarkus-resteasy`. + +Relocations have been put into place to not break your applications but we recommend that you adjust your applications already as these particular artifacts (`quarkus-rest-client*`) will be switched to RESTEasy Reactive in Quarkus 3.9. + +See https://github.com/quarkusio/quarkus/blob/main/adr/0002-reactive-rename.adoc for the full context about this change. + +The following table summarizes the changes: + +|=== +|Old name |New name + +|quarkus-rest-client +|quarkus-resteasy-client + +|quarkus-rest-client-jackson +|quarkus-resteasy-client-jackson + +|quarkus-rest-client-jaxb +|quarkus-resteasy-client-jaxb + +|quarkus-rest-client-jsonb +|quarkus-resteasy-client-jsonb + +|quarkus-rest-client-mutiny +|quarkus-resteasy-client-mutiny +|=== + +== JPA / Hibernate ORM + +=== Upgrade to Hibernate ORM 6.4 + +The Quarkus extensions for Hibernate ORM was upgraded to Hibernate ORM 6.4. + +Here are the most impactful changes: + +* Compatibility with some older database versions was dropped. ++ +See https://docs.jboss.org/hibernate/orm/6.4/dialect/dialect.html[here] for supported versions. +* https://github.com/hibernate/hibernate-orm/blob/6.3/migration-guide.adoc#hql-null-literal-comparison[The HQL `!=`/`<>` operators no longer allow comparing against `null`] +* https://github.com/hibernate/hibernate-orm/blob/6.3/migration-guide.adoc#hql-numeric-literal-types[Numeric literals are now interpreted as defined in Jakarta Persistence 3.2] + +See the Hibernate ORM migration guides for more details: + +* https://github.com/hibernate/hibernate-orm/blob/6.3/migration-guide.adoc[here for migration from 6.2 to 6.3] +* https://github.com/hibernate/hibernate-orm/blob/6.4.0/migration-guide.adoc[here for migration from 6.3 to 6.4] + +[[jpamodelgen]] +=== Static metamodel annotation processor (`hibernate-jpamodelgen`) can no longer be used as a `provided` dependency :gear: :white_check_mark: + +Some projects used to apply the `hibernate-jpamodelgen` annotation processor with a dependency, like so: + +```xml + + + + + org.hibernate.orm + hibernate-jpamodelgen + provided + 6.2.4 + + + +``` + +This is actually wrong for several reasons, one of them being that dependencies of the annotation processor may not be handled correctly. + +With Hibernate ORM 6.4, this annotation processor now has more dependencies, and https://github.com/hibernate/hibernate-orm/blob/6.3/migration-guide.adoc#integrating-static-metamodel-generation[the snippet above will fail, most likely with an error about an ANTLR class not being available]. + +Applications using Hibernate ORM 6.4+ (and thus Quarkus 3.7+) should register the `hibernate-jpamodelgen` annotation processor using the proper solution depending on their building tool. + +https://docs.jboss.org/hibernate/orm/6.4/userguide/html_single/Hibernate_User_Guide.html#tooling-maven-modelgen[With Maven]: + +```xml + + + [...] + + org.apache.maven.plugins + maven-compiler-plugin + 3.12.0 + + + + org.hibernate.orm + hibernate-jpamodelgen + + + + + [...] + + +``` + +[NOTE] +==== +Make sure you're using Maven Compiler Plugin 3.12.0 or later: +https://issues.apache.org/jira/browse/MCOMPILER-391[older versions didn't handle dependency management for `annotationProcessorPaths` entries], +forcing you to set the version of `hibernate-jpamodelgen` manually, even if you use the Quarkus BOM. +==== + +[NOTE] +==== +At the time of this writing, some IDEs https://github.com/eclipse-m2e/m2e-core/issues/1644[such as Eclipse], VSCode and most web-based IDEs do not handle dependency management for `annotationProcessorPaths` entries. +So you will have to set the version of `hibernate-jpamodelgen` manually, even if you use the Quarkus BOM: + +```xml + + + [...] + + org.apache.maven.plugins + maven-compiler-plugin + 3.12.0 + + + + org.hibernate.orm + hibernate-jpamodelgen + 6.4.2.Final + + + + + [...] + + +``` +==== + +https://docs.jboss.org/hibernate/orm/6.3/userguide/html_single/Hibernate_User_Guide.html#tooling-gradle-modelgen[With Gradle]: + +``` +dependencies { + annotationProcessor "org.hibernate.orm:hibernate-jpamodelgen" +} +``` + +== Hibernate Search + +=== Upgrade to Hibernate Search 7.0 + +The Quarkus extensions for Hibernate Search was upgraded to Hibernate Search 7.0. + +Here are the most impactful changes: + +* The values accepted by configuration properties `quarkus.hibernate-search-orm.coordination.entity-mapping.outbox-event.uuid-type` and `quarkus.hibernate-search-orm.coordination.entity-mapping.agent.uuid-type` changed: +** `uuid-binary` is deprecated in favor of `binary` +** `uuid-char` is deprecated in favor of `char` +* The default value for `quarkus.hibernate-search-orm.elasticsearch.query.shard-failure.ignore` changed from `true` to `false`, +meaning that Hibernate Search will now throw an exception if at least one shard failed during a search operation. ++ +To get the previous behavior set this configuration property explicitly to `true`. ++ +Note this configuration property must be set for each Elasticsearch backend, if you define multiple backends. +* The complement operator (`~`) in the https://docs.jboss.org/hibernate/search/7.0/reference/en-US/html_single/#search-dsl-predicate-regexp-flags[regular expression predicate] was removed with no alternative to replace it. +* The corresponding Hibernate Search dependencies no longer have an `-orm6` suffix in their artifact ID; +for example applications will now depend on `hibernate-search-mapper-orm` instead of `hibernate-search-mapper-orm-orm6`. + +See the https://docs.jboss.org/hibernate/search/7.0/migration/html_single/[Hibernate Search 7.0 migration guide] for more details. + +=== Database schema changed for outbox-polling system tables + +The https://quarkus.io/guides/hibernate-search-orm-elasticsearch#coordination[Quarkus extension for Hibernate Search with outbox-polling] +relies on system tables in your database, +and the schema of these system tables changed. + +See https://docs.jboss.org/hibernate/search/7.0/migration/html_single/#outboxpolling[this section of the Hibernate Search migration guide] for information on how to migrate your database schema if you were using that extension. + +=== `quarkus-hibernate-search-orm-coordination-outbox-polling` was renamed :gear: :white_check_mark: + +The https://quarkus.io/guides/hibernate-search-orm-elasticsearch#coordination[Quarkus extension for Hibernate Search with outbox-polling] was renamed: + +* The extension's artifact ID was renamed from `quarkus-hibernate-search-orm-coordination-outbox-polling` to `quarkus-hibernate-search-orm-outbox-polling` +* The base package in the corresponding Hibernate Search dependency changed from `org.hibernate.search.mapper.orm.coordination.outboxpolling` to `org.hibernate.search.mapper.orm.outboxpolling` + +== Scheduler - OpenTelemetry Tracing + +The integration of OpenTelemetry Tracing and Scheduler has been refactored. +Previously, only `@Scheduled` methods had a new `io.opentelemetry.api.trace.Span` associated automatically when tracing is enabled, i.e. when the `quarkus.scheduler.tracing.enabled` configuration property is set to `true` and the OpenTelemetry extension is present. +Since Quarkus 3.7, all scheduled jobs (including the jobs scheduled programmatically) have a `Span` associated automatically when tracing is enabled. +Furthermore, the unique job identifier (specified with `Scheduled.identity()` or `JobDefinition`) is used as a span name. +Previously, the span names followed the `.` format. + +== Okhttp/Okio versions not enforced anymore + +Okhttp and Okio versions are not enforced by the Quarkus BOM anymore. + +Make sure you define the versions in your build files if you are using any of these dependencies. + +== Infinispan + +The `quarkus-test-infinispan-client` artifact has been retired. +We don't think it was used outside of the Quarkus core repository and it wasn't used anymore even there since the introduction of Dev Services for Infinispan. + +== Insecure HTTP port is disabled when mTLS client authentication is required + +_PLain_ HTTP port is now disabled by default when an `mTLS` client authentication is required. +For example, if you have enabled `mTLS` with the following configuration: + +[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 +---- + +Then, attempts to access the Quarkus endpoint over an insecure (not `https://`) HTTP URL such as `http://localhost:8080/service` will fail because it has been requested by the server that the client sends a certificate to validate its identity. This mechanism is enforced at the transport level. + +This stricter policy has been enforced to avoid unexpected insecure HTTP requests reaching Quarkus applications that do not use the Quarkus Security https://quarkus.io/guides/security-authentication-mechanisms#mutual-tls[`mTLS` authentication mechanism]. + +If you need to allow insecure HTTP requests when an `mTLS` client authentication is required then you can enable such requests with `quarkus.http.insecure-requests=enabled`. However, if it is indeed necessary, it is recommended and simpler to use an `mTLs` client authentication `request` mode instead, for example: + +[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=request +---- + +== Stork + +The configurations names `stork."service-name".load-balancer` or `quarkus.stork."service-name".load-balancer` are not used anymore to configure the Stork load-balancer. Please use `quarkus.stork."service-name".load-balancer.type` instead. + +== OpenTelemetry + +It is now possible to disable particular automatic tracing instrumentations done within the OpenTelemetry extension. +The new configs are: + +* `quarkus.otel.instrument.grpc` +* `quarkus.otel.instrument.reactive-messaging` +* `quarkus.otel.instrument.rest-client-classic` +* `quarkus.otel.instrument.resteasy-reactive` +* `quarkus.otel.instrument.resteasy-classic` +* `quarkus.otel.instrument.vertx-http` +* `quarkus.otel.instrument.vertx-event-bus` +* `quarkus.otel.instrument.vertx-sql-client` + +The properties are booleans and are all `true` by default. + +== Resolving OIDC tenants with annotations for RESTEasy Classic applications + +Using CDI annotations and interceptors to resolve OIDC tenants for RESTEasy Classic applications is no longer possible due to the security checks now enforced before the CDI interceptors are triggered. +Use the `@io.quarkus.oidc.Tenant` annotation instead, which works both for RESTEasy Reactive and Classic applications. See https://quarkus.io/guides/security-openid-connect-multitenancy#annotations-tenant-resolver[Quarkus OIDC tenant resolution using annotations] for more information. + +== OpenShift +=== Deprecation of DeploymentConfig +As now DeploymentConfig resource are deprecated in OpenShift the default deployment kind for Openshift is now Deployment. +Applications that have been already deployed as DeploymentConfig that are redeployed will get a Deployment without having the old DeploymentConfig removed, leading to both new and old application to be deployed. Please ensure that the old (DeploymentConfig) is manually removed. Alternatively, you can explicitly set `quarkus.openshift.deployment-kind` to `DeploymentConfig` to retain the old behavior. \ No newline at end of file diff --git a/migration/Migration-Guide-3.8.asciidoc b/migration/Migration-Guide-3.8.asciidoc new file mode 100644 index 0000000000..331a42f4b9 --- /dev/null +++ b/migration/Migration-Guide-3.8.asciidoc @@ -0,0 +1,41 @@ +:toc: + +[NOTE] +==== +We highly recommend the use of https://quarkus.io/guides/update-quarkus[`quarkus update`] to update to a new version of Quarkus. + +Items marked below with :gear: :white_check_mark: are automatically handled by https://quarkus.io/guides/update-quarkus[`quarkus update`]. +==== + +**Quarkus 3.8 is an LTS version and the direct continuation of the 3.7 branch.** + +== Breaking Changes + +=== (3.8.1) Vert.x TCP Clients need to set the hostname verification algorithm + +Until now, when a Vert.x TCP client establishes a TLS connection without setting the hostname verification algorithm, `""` was used as the algorithm. `""` skips the validation, meaning that you can be affected by man-in-the-middle attacks. +This behavior changed in Vert.x 4.5.4 (integrated into Quarkus 3.8.1), as now, when establishing a TLS connection, the verification hostname algorithm must be set explicitly. It can be set to `NONE` (in the Quarkus configuration) or `""` (programmatically) to have the same behavior. + +This change of behavior only affects users explicitly creating Vert.x TCP clients directly (`with Vertx.createNetClient()`) + +=== (3.8.3) GraalVM SDK update :gear: :white_check_mark: + +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. + + +=== (3.8.3) Qute templates are not included in a generated native image on Windows + +The https://quarkus.io/guides/all-config#quarkus-core_quarkus-native-resources-includes[`quarkus.native.resources.includes`] configuration property can be used as a workaround. +For example, `quarkus.native.resources.includes=**/*.html` will add all html files located in the `src/main/resources` directory and all subdirectories. \ No newline at end of file diff --git a/migration/Migration-Guide-3.9.asciidoc b/migration/Migration-Guide-3.9.asciidoc new file mode 100644 index 0000000000..1862a34610 --- /dev/null +++ b/migration/Migration-Guide-3.9.asciidoc @@ -0,0 +1,539 @@ +:toc: + +[NOTE] +==== +We highly recommend the use of https://quarkus.io/guides/update-quarkus[`quarkus update`] to update to a new version of Quarkus. + +Items marked below with :gear: :white_check_mark: are automatically handled by https://quarkus.io/guides/update-quarkus[`quarkus update`]. +==== + +== RESTEasy Reactive extensions renamed to Quarkus REST :gear: :white_check_mark: + +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: + +[cols="1,1"] +|=== +|Old config root|New config 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 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 +|=== + +== SmallRye Reactive Messaging extensions renamed to Quarkus Messaging :gear: :white_check_mark: + +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 +|=== + +[[ormhrmongo-panache-annotation-processor-removed]] +== Panache annotation processor removed for Hibernate ORM/Hibernate Reactive/MongoDB :gear: :white_check_mark: + +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: + +```xml + + + [...] + + org.apache.maven.plugins + maven-compiler-plugin + 3.12.0 + + + + io.quarkus + quarkus-panache-common + + + + + [...] + + +``` + +For Gradle, this would be located here: + +``` +dependencies { + annotationProcessor "io.quarkus:quarkus-panache-common" +} +``` + +== OpenTelemetry + +=== Semantic convention changes + +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 https://quarkus.io/guides/opentelemetry#configuration-reference[configuration reference] for more details and full set of changes at the https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/migration-guide.md#summary-of-changes[HTTP semantic convention stability migration guide] from OpenTelemetry. + +=== Security events as OTel Events + +Quarkus now has the ability to export security events as OpenTelemetry Events, stored inside spans. This is not done by default and to activate you must to set this build time (only) configuration property: + +``` +quarkus.otel.security-events.enabled=true +``` + +== RESTEasy Reactive: Adding web links programmatically + +The HAL wrappers class signatures have been updated to include the type of elements in the collection as listed below. + +* `HalCollectionWrapper` +* `HalEntityWrapper` + +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: + +[source,java] +---- +@Path("/records") +public class RecordsResource { + + @Inject + HalService halService; + + @GET + @Produces({ MediaType.APPLICATION_JSON, RestMediaType.APPLICATION_HAL_JSON }) + @RestLink(rel = "list") + public HalCollectionWrapper getAll() { + List list = // ... + HalCollectionWrapper 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 get(@PathParam("id") int id) { + Record entity = // ... + HalEntityWrapper halEntity = halService.toHalWrapper(entity); + // ... + return halEntity; + } +} +---- + +Creating the wrappers using the constructors will still work for now, but this might change in the future. + +== RESTEasy Reactive: Filters on non REST paths + +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: + +[source,java] +---- +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 { + @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. + +[[elasticsearch-opensearch]] +== Elasticsearch/OpenSearch + +[[elasticsearch-opensearch-dev-services]] +=== Dev Services + +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, https://quarkus.io/guides/elasticsearch-dev-services#configuring-the-image[configure the container image explicitly]. + + +== Hibernate Search + +=== Database schema changed for outbox-polling system tables + +The https://quarkus.io/guides/hibernate-search-orm-elasticsearch#coordination[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 https://docs.jboss.org/hibernate/search/7.1/migration/html_single/#outboxpolling[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: + ```properties + 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: + ```properties + 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 + ``` + +== Update to Infinispan 15 + +Prior to Quarkus 3.9 and the Infinispan 15 integration, queries were executed by calling the following code: +.Query.java +[source,java] +---- +QueryFactory queryFactory = Search.getQueryFactory(booksCache); <1> +Query query = queryFactory.create("from book_sample.Book"); +List list = query.execute().list(); +---- +<1> 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. + +[source,java] +---- +Query query = booksCache.query("from book_sample.Book"); +List list = query.execute().list(); +---- + +== Keystore and trust store default format change + +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. + +[[junitpioneer-removed]] +== JUnit Pioneer version not enforced anymore + +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. + +== GraalVM SDK update :gear: :white_check_mark: + +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. + +== `quarkus-app` directory creation + +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). \ No newline at end of file diff --git a/migration/Migration-Guides.asciidoc b/migration/Migration-Guides.asciidoc new file mode 100644 index 0000000000..c45ecb7682 --- /dev/null +++ b/migration/Migration-Guides.asciidoc @@ -0,0 +1,47 @@ + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.16[main], will be 3.16 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.15[3.15] **LTS** - to be released + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.14[3.14] - released on Aug 28th 2024 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.13[3.13] - released on Jul 31st 2024 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.12[3.12] - released on Jun 26th 2024 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.11[3.11] - released on May 29th 2024 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.10[3.10] - released on Apr 30th 2024 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.9[3.9] - released on Mar 27th 2024 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.8[3.8] **LTS** - released on Feb 28th 2024 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.7[3.7] - released on Jan 31st 2024 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.6[3.6] - released on Nov 29th 2023 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.5[3.5] - released on Oct 25th 2023 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.4[3.4] - released on Sep 30th 2023 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.3[3.3] - released on Aug 23rd 2023 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.2[3.2] **LTS** - released on Jul 5th 2023 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.1[3.1] - released on May 31st 2023 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.0[3.0] - released on April 26th 2023 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.16[2.16] - released on January 25th 2023 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.15[2.15] - released on December 14th 2022 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.14[2.14] - released on November 9th 2022 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.13[2.13] - released on September 28th 2022 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.12[2.12] - released on August 31st 2022 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.11[2.11] - released on July 27th 2022 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.10[2.10] - released on June 21st 2022 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.9[2.9] - released on May 11th 2022 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.8[2.8] - released on Apr 12th 2022 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.7[2.7] - released on Feb 2nd 2022 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.6[2.6] - released on Dec 22nd 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.5[2.5] - released on Nov 24th 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.4[2.4] - released on Oct 27th 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.3[2.3] - released on Oct 6th 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.2[2.2] - released on Aug 31st 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.1[2.1] - released on Jul 29th 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-2.0[2.0] - released on Jun 30th 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.13[1.13] - released on Mar 30th 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.12[1.12] - released on Feb 23rd 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.11[1.11] - released on Jan 20th 2021 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.10[1.10] - released on Nov 25th 2020 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.9[1.9] - released on Oct 21th 2020 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.8[1.8] - released on Sep 15th 2020 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.7[1.7] - released on Aug 13th 2020 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.6[1.6] - released on Jul 8th 2020 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.5[1.5] - released on Jun 3rd 2020 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.4[1.4] - released on Apr 27th 2020 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.3[1.3] - released on Mar 19th 2020 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.2[1.2] - released on Jan 28th 2020 + * https://github.com/quarkusio/quarkus/wiki/Migration-Guide-1.1[1.1] - released on Dec 23th 2019 \ No newline at end of file