From d857ea8ec2d44379de6bd298601cd07bc09f5af4 Mon Sep 17 00:00:00 2001 From: Pedro Igor Date: Fri, 31 Mar 2023 09:36:02 -0300 Subject: [PATCH] Removing custom classloader and allow loading drivers at runtime Closes #13205 Co-authored-by: Brett Lounsbury --- docs/guides/server/db.adoc | 13 ++++++ .../org/keycloak/config/DatabaseOptions.java | 3 +- .../quarkus/runtime/KeycloakClassLoader.java | 42 ------------------- .../quarkus/runtime/KeycloakMain.java | 6 --- .../mappers/DatabasePropertyMappers.java | 1 + .../keycloak/it/cli/OptionValidationTest.java | 6 +-- ...dDistTest.testExportHelp.unix.approved.txt | 2 + ...stTest.testExportHelpAll.unix.approved.txt | 2 + ...dDistTest.testImportHelp.unix.approved.txt | 2 + ...stTest.testImportHelpAll.unix.approved.txt | 2 + ...istTest.testStartDevHelp.unix.approved.txt | 4 +- ...Test.testStartDevHelpAll.unix.approved.txt | 4 +- ...ndDistTest.testStartHelp.unix.approved.txt | 4 +- ...istTest.testStartHelpAll.unix.approved.txt | 4 +- ...t.testStartOptimizedHelp.unix.approved.txt | 2 + ...estStartOptimizedHelpAll.unix.approved.txt | 4 +- 16 files changed, 43 insertions(+), 58 deletions(-) delete mode 100644 quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakClassLoader.java diff --git a/docs/guides/server/db.adoc b/docs/guides/server/db.adoc index b230ead842..61f7fd1f92 100644 --- a/docs/guides/server/db.adoc +++ b/docs/guides/server/db.adoc @@ -57,6 +57,19 @@ The following is a sample command for a PostgreSQL database. Be aware that you need to escape characters when invoking commands containing special shell characters such as `;` using the CLI, so you might want to set it in the configuration file instead. +== Overriding the default JDBC driver + +The server uses a default JDBC driver accordingly to the database you chose. + +To set a different driver you can set the `db-driver` with the fully qualified class name of the JDBC driver: + +<@kc.start parameters="--db postgres --db-driver=my.Driver"/> + +Regardless of the driver you set, the default driver is always available at runtime. + +Only set this property if you really need to. For instance, when leveraging the capabilities from a JDBC Driver Wrapper for +a specific cloud database service. + == Configuring Unicode support for the database Unicode support for all fields depends on whether the database allows VARCHAR and CHAR fields to use the Unicode character set. diff --git a/quarkus/config-api/src/main/java/org/keycloak/config/DatabaseOptions.java b/quarkus/config-api/src/main/java/org/keycloak/config/DatabaseOptions.java index bc65e2554c..1e17ac9482 100644 --- a/quarkus/config-api/src/main/java/org/keycloak/config/DatabaseOptions.java +++ b/quarkus/config-api/src/main/java/org/keycloak/config/DatabaseOptions.java @@ -12,8 +12,7 @@ public class DatabaseOptions { public static final Option DB_DRIVER = new OptionBuilder<>("db-driver", String.class) .category(OptionCategory.DATABASE) - .hidden() - .defaultValue(Database.getDriver("dev-file", true).get()) + .description("The fully qualified class name of the JDBC driver. If not set, a default driver is set accordingly to the chosen database.") .build(); public static final Option DB = new OptionBuilder<>("db", String.class) diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakClassLoader.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakClassLoader.java deleted file mode 100644 index 507e7f6afa..0000000000 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakClassLoader.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2021 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.quarkus.runtime; - -import java.io.IOException; -import java.net.URL; -import java.sql.Driver; -import java.util.Collections; -import java.util.Enumeration; - -public class KeycloakClassLoader extends ClassLoader { - - KeycloakClassLoader() { - super(Thread.currentThread().getContextClassLoader()); - } - - @Override - public Enumeration getResources(String name) throws IOException { - // drivers are going to be loaded lazily, and we avoid loading all available drivers - // see https://github.com/quarkusio/quarkus/pull/7089 - if (name.contains(Driver.class.getName())) { - return Collections.emptyEnumeration(); - } - - return super.getResources(name); - } -} diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java index fa08875f3d..cf74b35653 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java @@ -94,11 +94,7 @@ public class KeycloakMain implements QuarkusApplication { } public static void start(ExecutionExceptionHandler errorHandler, PrintWriter errStream, String[] args) { - ClassLoader originalCl = Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader(new KeycloakClassLoader()); - Quarkus.run(KeycloakMain.class, (exitCode, cause) -> { if (cause != null) { errorHandler.error(errStream, @@ -117,8 +113,6 @@ public class KeycloakMain implements QuarkusApplication { String.format("Unexpected error when starting the server in (%s) mode", getKeycloakModeFromProfile(getProfileOrDefault("prod"))), cause.getCause()); System.exit(1); - } finally { - Thread.currentThread().setContextClassLoader(originalCl); } } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/DatabasePropertyMappers.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/DatabasePropertyMappers.java index 9b58561db9..5fcb452962 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/DatabasePropertyMappers.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/DatabasePropertyMappers.java @@ -34,6 +34,7 @@ final class DatabasePropertyMappers { .mapFrom("db") .to("quarkus.datasource.jdbc.driver") .transformer(DatabasePropertyMappers::getXaOrNonXaDriver) + .paramLabel("driver") .build(), fromOption(DatabaseOptions.DB) .transformer(DatabasePropertyMappers::resolveDatabaseVendor) diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/OptionValidationTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/OptionValidationTest.java index 79d88afff1..2bc244a6fa 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/OptionValidationTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/OptionValidationTest.java @@ -59,7 +59,7 @@ public class OptionValidationTest { public void failUnknownOptionWhitespaceSeparatorNotShowingValue(LaunchResult result) { CLIResult cliResult = (CLIResult) result; assertEquals("Unknown option: '--db-pasword'\n" + - "Possible solutions: --db-url, --db-url-host, --db-url-database, --db-url-port, --db-url-properties, --db-username, --db-password, --db-schema, --db-pool-initial-size, --db-pool-min-size, --db-pool-max-size, --db\n" + + "Possible solutions: --db-driver, --db-url, --db-url-host, --db-url-database, --db-url-port, --db-url-properties, --db-username, --db-password, --db-schema, --db-pool-initial-size, --db-pool-min-size, --db-pool-max-size, --db\n" + "Try '" + KeycloakDistribution.SCRIPT_CMD + " start --help' for more information on the available options.", cliResult.getErrorOutput()); } @@ -68,7 +68,7 @@ public class OptionValidationTest { public void failUnknownOptionEqualsSeparatorNotShowingValue(LaunchResult result) { CLIResult cliResult = (CLIResult) result; assertEquals("Unknown option: '--db-pasword'\n" + - "Possible solutions: --db-url, --db-url-host, --db-url-database, --db-url-port, --db-url-properties, --db-username, --db-password, --db-schema, --db-pool-initial-size, --db-pool-min-size, --db-pool-max-size, --db\n" + + "Possible solutions: --db-driver, --db-url, --db-url-host, --db-url-database, --db-url-port, --db-url-properties, --db-username, --db-password, --db-schema, --db-pool-initial-size, --db-pool-min-size, --db-pool-max-size, --db\n" + "Try '" + KeycloakDistribution.SCRIPT_CMD + " start --help' for more information on the available options.", cliResult.getErrorOutput()); } @@ -77,7 +77,7 @@ public class OptionValidationTest { public void failWithFirstOptionOnMultipleUnknownOptions(LaunchResult result) { CLIResult cliResult = (CLIResult) result; assertEquals("Unknown option: '--db-pasword'\n" + - "Possible solutions: --db-url, --db-url-host, --db-url-database, --db-url-port, --db-url-properties, --db-username, --db-password, --db-schema, --db-pool-initial-size, --db-pool-min-size, --db-pool-max-size, --db\n" + + "Possible solutions: --db-driver, --db-url, --db-url-host, --db-url-database, --db-url-port, --db-url-properties, --db-username, --db-password, --db-schema, --db-pool-initial-size, --db-pool-min-size, --db-pool-max-size, --db\n" + "Try '" + KeycloakDistribution.SCRIPT_CMD + " start --help' for more information on the available options.", cliResult.getErrorOutput()); } } diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelp.unix.approved.txt index 60b69fb3dc..ad8eb390c4 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelp.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelp.unix.approved.txt @@ -13,6 +13,8 @@ Options: Database: +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelpAll.unix.approved.txt index c5338f6362..d2f01f4f1f 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelpAll.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelpAll.unix.approved.txt @@ -32,6 +32,8 @@ Storage (Experimental): Database: +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelp.unix.approved.txt index 6f5efab0b5..acb0e00508 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelp.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelp.unix.approved.txt @@ -13,6 +13,8 @@ Options: Database: +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelpAll.unix.approved.txt index dadc355b1e..f4d068dd9b 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelpAll.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelpAll.unix.approved.txt @@ -32,6 +32,8 @@ Storage (Experimental): Database: +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.unix.approved.txt index 909d2fea7a..cb3706d982 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.unix.approved.txt @@ -32,6 +32,8 @@ Database: --db The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres. Default: dev-file. +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size @@ -223,4 +225,4 @@ Logging: Do NOT start the server using this command when deploying to production. Use 'kc.sh start-dev --help-all' to list all available options, including build -options. +options. \ No newline at end of file diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.unix.approved.txt index e48c8f1e9e..601568cfdf 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.unix.approved.txt @@ -95,6 +95,8 @@ Database: --db The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres. Default: dev-file. +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size @@ -292,4 +294,4 @@ Security (Preview): Do NOT start the server using this command when deploying to production. Use 'kc.sh start-dev --help-all' to list all available options, including build -options. +options. \ No newline at end of file diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.unix.approved.txt index f6c42ce599..a26e31de98 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.unix.approved.txt @@ -38,6 +38,8 @@ Database: --db The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres. Default: dev-file. +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size @@ -233,4 +235,4 @@ By default, this command tries to update the server configuration by running a $ kc.sh start '--optimized' By doing that, the server should start faster based on any previous -configuration you have set when manually running the 'build' command. +configuration you have set when manually running the 'build' command. \ No newline at end of file diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.unix.approved.txt index dce36011b9..dbda02ff66 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.unix.approved.txt @@ -101,6 +101,8 @@ Database: --db The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres. Default: dev-file. +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size @@ -302,4 +304,4 @@ By default, this command tries to update the server configuration by running a $ kc.sh start '--optimized' By doing that, the server should start faster based on any previous -configuration you have set when manually running the 'build' command. +configuration you have set when manually running the 'build' command. \ No newline at end of file diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.unix.approved.txt index e31c9e3834..4cd485d847 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.unix.approved.txt @@ -22,6 +22,8 @@ Options: Database: +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.unix.approved.txt index bc7c4f5b33..cd13817d8e 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.unix.approved.txt @@ -41,6 +41,8 @@ Storage (Experimental): Database: +--db-driver The fully qualified class name of the JDBC driver. If not set, a default + driver is set accordingly to the chosen database. --db-password The password of the database user. --db-pool-initial-size @@ -197,4 +199,4 @@ By default, this command tries to update the server configuration by running a $ kc.sh start '--optimized' By doing that, the server should start faster based on any previous -configuration you have set when manually running the 'build' command. +configuration you have set when manually running the 'build' command. \ No newline at end of file