diff --git a/.github/workflows/ci-actions-incremental.yml b/.github/workflows/ci-actions-incremental.yml
index 086334df6de6d..e82fed04711a2 100644
--- a/.github/workflows/ci-actions-incremental.yml
+++ b/.github/workflows/ci-actions-incremental.yml
@@ -148,7 +148,7 @@ jobs:
env:
CAPTURE_BUILD_SCAN: true
run: |
- ./mvnw -T1C $COMMON_MAVEN_ARGS -DskipTests -DskipITs -DskipDocs -Dinvoker.skip -Dno-format -Dtcks -Prelocations clean install
+ ./mvnw -T1C $COMMON_MAVEN_ARGS -DskipTests -DskipITs -DskipDocs -Dinvoker.skip -Dskip.gradle.tests -Djbang.skip -Dtruststore.skip -Dno-format -Dtcks -Prelocations clean install
- name: Verify extension dependencies
run: ./update-extension-dependencies.sh $COMMON_MAVEN_ARGS
- name: Get GIB arguments
diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index 059718fa95e2c..729acf449a32b 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -24,7 +24,7 @@
1.3.2
1
1.1.5
- 2.1.4.Final
+ 2.1.5.Final
3.1.0.Final
6.2.7.Final
0.33.0
@@ -100,7 +100,7 @@
bytebuddy.version (just below), hibernate-orm.version-for-documentation (in docs/pom.xml)
and both hibernate-orm.version and antlr.version in build-parent/pom.xml
WARNING again for diffs that don't provide enough context: when updating, see above -->
- 6.4.1.Final
+ 6.4.2.Final
1.14.7
6.0.6.Final
2.2.1.Final
@@ -144,11 +144,11 @@
14.0.21.Final
4.6.5.Final
3.1.5
- 4.1.103.Final
+ 4.1.106.Final
1.12.0
1.0.4
3.5.3.Final
- 2.5.3
+ 2.5.4
3.6.1
1.8.0
1.1.10.5
@@ -188,8 +188,8 @@
5.8.0
5.8.0
4.13.0
- 2.0.2.Final
- 23.0.3
+ 2.0.3.Final
+ 23.0.4
1.15.1
3.42.0
2.24.0
@@ -221,7 +221,7 @@
9.37.3
0.0.6
0.1.3
- 2.10.0
+ 2.12.0
0.8.9
1.0.0
3.0.0
diff --git a/build-parent/pom.xml b/build-parent/pom.xml
index 13cb7562806c8..8e65e4e5d157f 100644
--- a/build-parent/pom.xml
+++ b/build-parent/pom.xml
@@ -104,7 +104,7 @@
- 23.0.3
+ 23.0.4
19.0.3
quay.io/keycloak/keycloak:${keycloak.version}
quay.io/keycloak/keycloak:${keycloak.wildfly.version}-legacy
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleCommand.java b/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleCommand.java
index 73eaf0a311231..8c0d56ba3036c 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleCommand.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleCommand.java
@@ -39,6 +39,16 @@ public ConsoleCommand(char key, String description, HelpState helpState, Runnabl
this(key, description, null, -1, helpState, runnable);
}
+ public static ConsoleCommand duplicateCommandWithNewPromptString(ConsoleCommand commandToDuplicate,
+ String newPromptString) {
+ return new ConsoleCommand(commandToDuplicate.getKey(),
+ commandToDuplicate.getDescription(),
+ newPromptString,
+ commandToDuplicate.getPromptPriority(),
+ commandToDuplicate.getHelpState(),
+ commandToDuplicate.getReadLineHandler());
+ }
+
public char getKey() {
return key;
}
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleStateManager.java b/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleStateManager.java
index a344770dc0d83..6b891851e5ddc 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleStateManager.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleStateManager.java
@@ -100,15 +100,20 @@ public static void init(QuarkusConsole console, DevModeType devModeType) {
}
void installBuiltins(DevModeType devModeType) {
+ final String editPromptFormat = "to edit command line args (currently '"
+ + MessageFormat.GREEN
+ + "%s"
+ + MessageFormat.RESET
+ + "')";
+ ConsoleContext context = createContext("System");
List commands = new ArrayList<>();
if (devModeType != DevModeType.TEST_ONLY) {
commands.add(new ConsoleCommand('s', "Force restart", null, () -> {
forceRestart();
}));
commands.add(new ConsoleCommand('e', "Edits the command line parameters and restarts",
- "to edit command line args (currently '" + MessageFormat.GREEN
- + String.join(" ", RuntimeUpdatesProcessor.INSTANCE.getCommandLineArgs()) + MessageFormat.RESET
- + "')",
+ editPromptFormat.formatted(String.join(" ",
+ RuntimeUpdatesProcessor.INSTANCE.getCommandLineArgs())),
100, new ConsoleCommand.HelpState(() -> BLUE,
() -> String.join(" ", RuntimeUpdatesProcessor.INSTANCE.getCommandLineArgs())),
new Consumer() {
@@ -121,6 +126,10 @@ public void accept(String args) {
Logger.getLogger(ConsoleStateManager.class).errorf(e, "Failed to parse command line %s", args);
return;
}
+ // Reload command prompt string
+ context.reset(ConsoleCommand.duplicateCommandWithNewPromptString(context.getCommandByKey('e'),
+ editPromptFormat.formatted(String.join(" ",
+ RuntimeUpdatesProcessor.INSTANCE.getCommandLineArgs()))));
RuntimeUpdatesProcessor.INSTANCE.doScan(true, true);
}
}));
@@ -145,8 +154,6 @@ public void accept(String args) {
}));
}
- ConsoleContext context = createContext("System");
-
commands.add(new ConsoleCommand('j', "Toggle log levels",
new ConsoleCommand.HelpState(() -> currentLevel == null ? BLUE : RED,
() -> (currentLevel == null
@@ -280,8 +287,9 @@ public ConsoleContext createContext(String name) {
void redraw() {
List sorted = commands.values().stream().map(s -> s.consoleCommand)
- .filter(s -> s.getPromptString() != null).sorted(Comparator.comparingInt(ConsoleCommand::getPromptPriority))
- .collect(Collectors.toList());
+ .filter(s -> s.getPromptString() != null)
+ .sorted(Comparator.comparingInt(ConsoleCommand::getPromptPriority))
+ .toList();
if (sorted.isEmpty()) {
QuarkusConsole.INSTANCE.setPromptMessage(null);
oldPrompt = null;
@@ -338,6 +346,12 @@ public void addCommandInternal(ConsoleCommand consoleCommand) {
}
}
+ public ConsoleCommand getCommandByKey(Character key) {
+ synchronized (commands) {
+ return commands.get(key).consoleCommand;
+ }
+ }
+
public void reset(ConsoleCommand... command) {
synchronized (commands) {
internal.clear();
diff --git a/devtools/cli/src/main/java/io/quarkus/cli/build/BuildSystemRunner.java b/devtools/cli/src/main/java/io/quarkus/cli/build/BuildSystemRunner.java
index 86fb31863deab..5a6fd63209125 100644
--- a/devtools/cli/src/main/java/io/quarkus/cli/build/BuildSystemRunner.java
+++ b/devtools/cli/src/main/java/io/quarkus/cli/build/BuildSystemRunner.java
@@ -71,10 +71,16 @@ default BuildCommandArgs prependExecutable(ArrayDeque args) {
default void paramsToQuarkusArgs(List params, ArrayDeque args) {
if (!params.isEmpty()) {
- args.add("-Dquarkus.args='" + String.join(" ", params) + "'");
+ args.add("-Dquarkus.args=" + String.join(" ", wrapWithDoubleQuotes(params)));
}
}
+ default List wrapWithDoubleQuotes(List stringsToWrap) {
+ return stringsToWrap.stream()
+ .map("\"%s\""::formatted)
+ .toList();
+ }
+
default List flattenMappedProperties(Map props) {
List result = new ArrayList<>();
props.entrySet().forEach(x -> {
diff --git a/devtools/cli/src/test/java/io/quarkus/cli/CliProjectGradleTest.java b/devtools/cli/src/test/java/io/quarkus/cli/CliProjectGradleTest.java
index 354ed4055f511..eb11e76ff4b91 100644
--- a/devtools/cli/src/test/java/io/quarkus/cli/CliProjectGradleTest.java
+++ b/devtools/cli/src/test/java/io/quarkus/cli/CliProjectGradleTest.java
@@ -348,8 +348,8 @@ public void testDevOptions() throws Exception {
Assertions.assertFalse(result.stdout.contains("-Dsuspend"),
"gradle command should not specify '-Dsuspend'\n" + result);
- Assertions.assertTrue(result.stdout.contains("-Dquarkus.args='arg1 arg2'"),
- "gradle command should not specify -Dquarkus.args='arg1 arg2'\n" + result);
+ Assertions.assertTrue(result.stdout.contains("-Dquarkus.args=\"arg1\" \"arg2\""),
+ "gradle command should not specify -Dquarkus.args=\"arg1\" \"arg2\"\n" + result);
// 4 TEST MODE: test --clean --debug --suspend --offline
result = CliDriver.execute(project, "test", "-e", "--dry-run",
@@ -366,6 +366,13 @@ public void testDevOptions() throws Exception {
"Expected OK return code. Result:\n" + result);
Assertions.assertTrue(result.stdout.contains("Run current project in test mode"), result.toString());
Assertions.assertTrue(result.stdout.contains("--tests FooTest"), result.toString());
+
+ // 6 TEST MODE: Two word argument
+ result = CliDriver.execute(project, "dev", "-e", "--dry-run",
+ "--no-suspend", "--debug-host=0.0.0.0", "--debug-port=8008", "--debug-mode=connect", "--", "arg1 arg2");
+
+ Assertions.assertTrue(result.stdout.contains("-Dquarkus.args=\"arg1 arg2\""),
+ "mvn command should not specify -Dquarkus.args=\"arg1 arg2\"\n" + result);
}
@Test
diff --git a/devtools/cli/src/test/java/io/quarkus/cli/CliProjectMavenTest.java b/devtools/cli/src/test/java/io/quarkus/cli/CliProjectMavenTest.java
index 180795f1ae0e3..1374448c5ab51 100644
--- a/devtools/cli/src/test/java/io/quarkus/cli/CliProjectMavenTest.java
+++ b/devtools/cli/src/test/java/io/quarkus/cli/CliProjectMavenTest.java
@@ -273,8 +273,8 @@ public void testDevTestOptions() throws Exception {
Assertions.assertFalse(result.stdout.contains("-Dsuspend"),
"mvn command should not specify '-Dsuspend'\n" + result);
- Assertions.assertTrue(result.stdout.contains("-Dquarkus.args='arg1 arg2'"),
- "mvn command should not specify -Dquarkus.args='arg1 arg2'\n" + result);
+ Assertions.assertTrue(result.stdout.contains("-Dquarkus.args=\"arg1\" \"arg2\""),
+ "mvn command should not specify -Dquarkus.args=\"arg1\" \"arg2\"\n" + result);
// 4 TEST MODE: test --clean --debug --suspend --offline
result = CliDriver.execute(project, "test", "-e", "--dry-run",
@@ -291,6 +291,13 @@ public void testDevTestOptions() throws Exception {
"Expected OK return code. Result:\n" + result);
Assertions.assertTrue(result.stdout.contains("Run current project in test mode"), result.toString());
Assertions.assertTrue(result.stdout.contains("-Dtest=FooTest"), result.toString());
+
+ // 6 TEST MODE: Two word argument
+ result = CliDriver.execute(project, "dev", "-e", "--dry-run",
+ "--no-suspend", "--debug-host=0.0.0.0", "--debug-port=8008", "--debug-mode=connect", "--", "arg1 arg2");
+
+ Assertions.assertTrue(result.stdout.contains("-Dquarkus.args=\"arg1 arg2\""),
+ "mvn command should not specify -Dquarkus.args=\"arg1 arg2\"\n" + result);
}
@Test
diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java
index 16a7742557386..942515adbefc8 100644
--- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java
+++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java
@@ -136,6 +136,7 @@ public void apply(Project project) {
final QuarkusPluginExtension quarkusExt = project.getExtensions().create(EXTENSION_NAME, QuarkusPluginExtension.class,
project);
+ createSourceSets(project);
createConfigurations(project);
registerTasks(project, quarkusExt);
}
@@ -323,7 +324,7 @@ public boolean isSatisfiedBy(Task t) {
quarkusGenerateCodeDev.configure(task -> task.setSourcesDirectories(getSourcesParents(mainSourceSet)));
quarkusGenerateCodeTests.configure(task -> task.setSourcesDirectories(getSourcesParents(testSourceSet)));
- SourceSet intTestSourceSet = sourceSets.create(INTEGRATION_TEST_SOURCE_SET_NAME);
+ SourceSet intTestSourceSet = sourceSets.getByName(INTEGRATION_TEST_SOURCE_SET_NAME);
intTestSourceSet.setCompileClasspath(
intTestSourceSet.getCompileClasspath()
.plus(mainSourceSet.getOutput())
@@ -345,7 +346,7 @@ public boolean isSatisfiedBy(Task t) {
intTestTask.setTestClassesDirs(intTestSourceOutputClasses);
});
- SourceSet nativeTestSourceSet = sourceSets.create(NATIVE_TEST_SOURCE_SET_NAME);
+ SourceSet nativeTestSourceSet = sourceSets.getByName(NATIVE_TEST_SOURCE_SET_NAME);
nativeTestSourceSet.setCompileClasspath(
nativeTestSourceSet.getCompileClasspath()
.plus(mainSourceSet.getOutput())
@@ -391,8 +392,8 @@ public void execute(Task task) {
// quarkusBuild is expected to run after the project has passed the tests
quarkusBuildCacheableAppParts.configure(task -> task.shouldRunAfter(tasks.withType(Test.class)));
- SourceSet generatedSourceSet = sourceSets.create(QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES);
- SourceSet generatedTestSourceSet = sourceSets.create(QuarkusGenerateCode.QUARKUS_TEST_GENERATED_SOURCES);
+ SourceSet generatedSourceSet = sourceSets.getByName(QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES);
+ SourceSet generatedTestSourceSet = sourceSets.getByName(QuarkusGenerateCode.QUARKUS_TEST_GENERATED_SOURCES);
// Register the quarkus-generated-code
for (String provider : QuarkusGenerateCode.CODE_GENERATION_PROVIDER) {
@@ -423,14 +424,22 @@ private static void configureGenerateCodeTask(QuarkusGenerateCode task, String g
task.getGeneratedOutputDirectory().set(generatedSources.getJava().getClassesDirectory().get().getAsFile());
}
+ private void createSourceSets(Project project) {
+ SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
+ sourceSets.create(INTEGRATION_TEST_SOURCE_SET_NAME);
+ sourceSets.create(NATIVE_TEST_SOURCE_SET_NAME);
+ sourceSets.create(QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES);
+ sourceSets.create(QuarkusGenerateCode.QUARKUS_TEST_GENERATED_SOURCES);
+ }
+
private void createConfigurations(Project project) {
final ConfigurationContainer configContainer = project.getConfigurations();
// Custom configuration to be used for the dependencies of the testNative task
- configContainer.maybeCreate(NATIVE_TEST_IMPLEMENTATION_CONFIGURATION_NAME)
+ configContainer.getByName(NATIVE_TEST_IMPLEMENTATION_CONFIGURATION_NAME)
.extendsFrom(configContainer.findByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME));
- configContainer.maybeCreate(NATIVE_TEST_RUNTIME_ONLY_CONFIGURATION_NAME)
+ configContainer.getByName(NATIVE_TEST_RUNTIME_ONLY_CONFIGURATION_NAME)
.extendsFrom(configContainer.findByName(JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME));
// create a custom configuration to be used for the dependencies of the quarkusIntTest task
diff --git a/docs/src/main/asciidoc/cdi.adoc b/docs/src/main/asciidoc/cdi.adoc
index 7d393c12f7b38..0cdc9da9d2fb3 100644
--- a/docs/src/main/asciidoc/cdi.adoc
+++ b/docs/src/main/asciidoc/cdi.adoc
@@ -253,7 +253,7 @@ Client proxies allow for:
* Circular dependencies in the dependency graph. Having circular dependencies is often an indication that a redesign should be considered, but sometimes it's inevitable.
* In rare cases it's practical to destroy the beans manually. A direct injected reference would lead to a stale bean instance.
-
+[[ok-you-said-that-there-are-several-kinds-of-beans]]
== OK. You said that there are several kinds of beans?
Yes. In general, we distinguish:
diff --git a/docs/src/main/asciidoc/config-reference.adoc b/docs/src/main/asciidoc/config-reference.adoc
index 8d68f8462abdf..286d6f5601177 100644
--- a/docs/src/main/asciidoc/config-reference.adoc
+++ b/docs/src/main/asciidoc/config-reference.adoc
@@ -329,6 +329,7 @@ By default, Quarkus provides three profiles, that activate automatically in cert
* *test* - Activated when running tests
* *prod* - The default profile when not running in development or test mode
+[[custom-profiles]]
=== Custom Profiles
It is also possible to create additional profiles and activate them with the `quarkus.profile` configuration property. A
diff --git a/docs/src/main/asciidoc/container-image.adoc b/docs/src/main/asciidoc/container-image.adoc
index eb5e7c3ebff19..2fd411e028c52 100644
--- a/docs/src/main/asciidoc/container-image.adoc
+++ b/docs/src/main/asciidoc/container-image.adoc
@@ -47,14 +47,14 @@ For example, the presence of `src/main/jib/foo/bar` would result in `/foo/bar`
There are cases where the built container image may need to have Java debugging conditionally enabled at runtime.
-When the base image has not been changed (and therefore `ubi8/openjdk-11-runtime`, `ubi8/openjdk-17-runtime`, or `ubi8/openjdk-21-runtime` is used), then the `quarkus.jib.jvm-arguments` configuration property can be used in order to
+When the base image has not been changed (and therefore `ubi8/openjdk-11-runtime`, `ubi8/openjdk-17-runtime`, or `ubi8/openjdk-21-runtime` is used), then the `quarkus.jib.jvm-additional-arguments` configuration property can be used in order to
make the JVM listen on the debug port at startup.
The exact configuration is:
[source,properties]
----
-quarkus.jib.jvm-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005
+quarkus.jib.jvm-additional-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005
----
Other base images might provide launch scripts that enable debugging when an environment variable is set, in which case you would set than environment variable when launching the container.
diff --git a/docs/src/main/asciidoc/datasource.adoc b/docs/src/main/asciidoc/datasource.adoc
index 81fbb90de0eba..74f7fcfcfd121 100644
--- a/docs/src/main/asciidoc/datasource.adoc
+++ b/docs/src/main/asciidoc/datasource.adoc
@@ -253,7 +253,12 @@ Without an extension, the driver will work correctly in any Quarkus app running
However, the driver is unlikely to work when compiling your application to a native executable.
If you plan to make a native executable, use the existing JDBC Quarkus extensions, or contribute one for your driver.
-.An example with the OpenTracing driver:
+[WARNING]
+====
+OpenTracing has been deprecated in favor of OpenTelemetry. For tracing information, please check the related section about <>, bellow.
+====
+
+.A custom driver definition example with the legacy OpenTracing driver:
[source, properties]
----
@@ -405,6 +410,99 @@ AgroalDataSource usersDataSource;
AgroalDataSource inventoryDataSource;
----
+[[datasource-active]]
+=== Activate/deactivate datasources
+
+If a datasource is configured at build time,
+by default it is active at runtime,
+that is Quarkus will start the corresponding JDBC connection pool or reactive client on application startup.
+
+To deactivate a datasource at runtime, set `quarkus.datasource[.optional name].active` to `false`.
+Then Quarkus will not start the corresponding JDBC connection pool or reactive client on application startup.
+Any attempt to use the corresponding datasource at runtime will fail with a clear error message.
+
+This is in particular useful when you want an application to be able
+to use one of a pre-determined set of datasources at runtime.
+
+[WARNING]
+====
+If another Quarkus extension relies on an inactive datasource,
+that extension might fail to start.
+
+In such case, you will need to deactivate that other extension too.
+For example see xref:hibernate-orm.adoc#persistence-unit-active[here for Hibernate ORM].
+====
+
+For example, with the following configuration:
+
+[source,properties]
+----
+quarkus.datasource."pg".db-kind=postgres
+quarkus.datasource."pg".active=false
+quarkus.datasource."pg".jdbc.url=jdbc:postgresql:///your_database
+
+quarkus.datasource."oracle".db-kind=oracle
+quarkus.datasource."oracle".active=false
+quarkus.datasource."oracle".jdbc.url=jdbc:oracle:///your_database
+----
+
+Setting `quarkus.datasource."pg".active=true` xref:config-reference.adoc#configuration-sources[at runtime]
+will make only the PostgreSQL datasource available,
+and setting `quarkus.datasource."oracle".active=true` at runtime
+will make only the Oracle datasource available.
+
+[TIP]
+====
+xref:config-reference.adoc#custom-profiles[Custom configuration profiles] can help simplify such a setup.
+By appending the following profile-specific configuration to the one above,
+you can select a persistence unit/datasource at runtime simply by
+xref:config-reference.adoc#multiple-profiles[setting `quarkus.profile`]:
+`quarkus.profile=prod,pg` or `quarkus.profile=prod,oracle`.
+
+[source,properties]
+----
+%pg.quarkus.hibernate-orm."pg".active=true
+%pg.quarkus.datasource."pg".active=true
+# Add any pg-related runtime configuration here, prefixed with "%pg."
+
+%oracle.quarkus.hibernate-orm."oracle".active=true
+%oracle.quarkus.datasource."oracle".active=true
+# Add any pg-related runtime configuration here, prefixed with "%pg."
+----
+====
+
+[TIP]
+====
+It can also be useful to define a xref:cdi.adoc#ok-you-said-that-there-are-several-kinds-of-beans[CDI bean producer] redirecting to the currently active datasource,
+like this:
+
+[source,java,indent=0]
+----
+public class MyProducer {
+ @Inject
+ DataSourceSupport dataSourceSupport;
+
+ @Inject
+ @DataSource("pg")
+ AgroalDataSource pgDataSourceBean;
+
+ @Inject
+ @DataSource("oracle")
+ AgroalDataSource oracleDataSourceBean;
+
+ @Produces
+ @ApplicationScoped
+ public AgroalDataSource dataSource() {
+ if (dataSourceSupport.getInactiveNames().contains("pg")) {
+ return oracleDataSourceBean;
+ } else {
+ return pgDataSourceBean;
+ }
+ }
+}
+----
+====
+
== Datasource integrations
=== Datasource health check
@@ -441,6 +539,20 @@ They are available after calling `dataSource.getMetrics()` on an injected `Agroa
If the metrics collection for this datasource is disabled, all values result in zero.
+[[datasource-tracing]]
+=== Datasource tracing
+
+To use tracing with a datasource, you need to add the xref:opentelemetry.adoc[`quarkus-opentelemetry`] extension to your project.
+
+You don't need to declare a different driver because you need tracing. If you use a JDBC driver, you need to follow the instructions in the OpenTelemetry extension xref:opentelemetry.adoc#jdbc[here].
+
+Even with all the tracing infrastructure in place the datasource tracing is not enabled by default, and you need to enable it by setting this property:
+[source, properties]
+----
+# enable tracing
+quarkus.datasource.jdbc.telemetry=true
+----
+
=== Narayana transaction manager integration
Integration is automatic if the Narayana JTA extension is also available.
diff --git a/docs/src/main/asciidoc/hibernate-orm.adoc b/docs/src/main/asciidoc/hibernate-orm.adoc
index 3439cbae1e469..ff704928e292f 100644
--- a/docs/src/main/asciidoc/hibernate-orm.adoc
+++ b/docs/src/main/asciidoc/hibernate-orm.adoc
@@ -464,6 +464,98 @@ You can inject the `EntityManagerFactory` of a named persistence unit using the
EntityManagerFactory entityManagerFactory;
----
+[[persistence-unit-active]]
+=== Activate/deactivate persistence units
+
+If a persistence unit is configured at build time,
+by default it is active at runtime,
+that is Quarkus will start the corresponding Hibernate ORM `SessionFactory` on application startup.
+
+To deactivate a persistence unit at runtime, set `quarkus.hibernate-orm[.optional name].active` to `false`.
+Then Quarkus will not start the corresponding Hibernate ORM `SessionFactory` on application startup.
+Any attempt to use the corresponding persistence unit at runtime will fail with a clear error message.
+
+This is in particular useful when you want an application to be able
+to xref:datasource.adoc#datasource-active[use one of a pre-determined set of datasources at runtime].
+
+For example, with the following configuration:
+
+[source,properties]
+----
+quarkus.hibernate-orm."pg".packages=org.acme.model.shared
+quarkus.hibernate-orm."pg".datasource=pg
+quarkus.hibernate-orm."pg".database.generation=drop-and-create
+quarkus.hibernate-orm."pg".active=false
+quarkus.datasource."pg".db-kind=h2
+quarkus.datasource."pg".active=false
+quarkus.datasource."pg".jdbc.url=jdbc:postgresql:///your_database
+
+quarkus.hibernate-orm."oracle".packages=org.acme.model.shared
+quarkus.hibernate-orm."oracle".datasource=oracle
+quarkus.hibernate-orm."oracle".database.generation=drop-and-create
+quarkus.hibernate-orm."oracle".active=false
+quarkus.datasource."oracle".db-kind=oracle
+quarkus.datasource."oracle".active=false
+quarkus.datasource."oracle".jdbc.url=jdbc:oracle:///your_database
+----
+
+xref:config-reference.adoc#configuration-sources[Setting] `quarkus.hibernate-orm."pg".active=true` and `quarkus.datasource."pg".active=true` at runtime
+will make only the PostgreSQL persistence unit and datasource available,
+and setting `quarkus.hibernate-orm."oracle".active=true` and `quarkus.datasource."oracle".active=true` at runtime
+will make only the Oracle persistence unit and datasource available.
+
+[TIP]
+====
+xref:config-reference.adoc#custom-profiles[Custom configuration profiles] can help simplify such a setup.
+By appending the following profile-specific configuration to the one above,
+you can select a persistence unit/datasource at runtime simply by
+xref:config-reference.adoc#multiple-profiles[setting `quarkus.profile`]:
+`quarkus.profile=prod,pg` or `quarkus.profile=prod,oracle`.
+
+[source,properties]
+----
+%pg.quarkus.hibernate-orm."pg".active=true
+%pg.quarkus.datasource."pg".active=true
+# Add any pg-related runtime configuration here, prefixed with "%pg."
+
+%oracle.quarkus.hibernate-orm."oracle".active=true
+%oracle.quarkus.datasource."oracle".active=true
+# Add any pg-related runtime configuration here, prefixed with "%pg."
+----
+====
+
+[TIP]
+====
+It can also be useful to define a xref:cdi.adoc#ok-you-said-that-there-are-several-kinds-of-beans[CDI bean producer] redirecting to the currently active persistence unit,
+like this:
+
+[source,java,indent=0]
+----
+public class MyProducer {
+ @Inject
+ DataSourceSupport dataSourceSupport;
+
+ @Inject
+ @PersistenceUnit("pg")
+ Session pgSessionBean;
+
+ @Inject
+ @PersistenceUnit("oracle")
+ Session oracleSessionBean;
+
+ @Produces
+ @ApplicationScoped
+ public Session session() {
+ if (dataSourceSupport.getInactiveNames().contains("pg")) {
+ return oracleSessionBean;
+ } else {
+ return pgSessionBean;
+ }
+ }
+}
+----
+====
+
[[persistence-xml]]
== Setting up and configuring Hibernate ORM with a `persistence.xml`
diff --git a/docs/src/main/asciidoc/qute-reference.adoc b/docs/src/main/asciidoc/qute-reference.adoc
index 8e4480d6b64ba..ba56d9283048c 100644
--- a/docs/src/main/asciidoc/qute-reference.adoc
+++ b/docs/src/main/asciidoc/qute-reference.adoc
@@ -223,7 +223,7 @@ Likewise, a line that contains an _expression_ or a _non-whitespace character_ i
<3>
{/for} <4>
-
+