8000 Error message when JDBC driver is missing is not helpful by mabartos · Pull Request #22934 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2023 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.deployment;

import io.quarkus.builder.item.EmptyBuildItem;

/**
* A barrier build item that can be consumed by other build steps when JDBC Driver is checked
*/
public class CheckJdbcBuildStep extends EmptyBuildItem {
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@
package org.keycloak.quarkus.deployment;

import io.quarkus.agroal.spi.JdbcDataSourceBuildItem;
import io.quarkus.agroal.spi.JdbcDriverBuildItem;
import io.quarkus.arc.deployment.BuildTimeConditionBuildItem;
import io.quarkus.bootstrap.logging.InitialConfigurator;
import io.quarkus.datasource.deployment.spi.DevServicesDatasourceResultBuildItem;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.Consume;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Produce;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.BootstrapConfigSetupCompleteBuildItem;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
Expand All @@ -39,6 +42,7 @@
import io.quarkus.hibernate.orm.deployment.PersistenceXmlDescriptorBuildItem;
import io.quarkus.hibernate.orm.deployment.integration.HibernateOrmIntegrationRuntimeConfiguredBuildItem;
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
import io.quarkus.runtime.configuration.ConfigurationException;
import io.quarkus.runtime.configuration.ProfileManager;
import io.quarkus.vertx.http.deployment.FilterBuildItem;
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
Expand Down Expand Up @@ -135,6 +139,7 @@
import java.util.function.Predicate;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Handler;

import static org.keycloak.connections.jpa.util.JpaUtils.loadSpecificNamedQueries;
import static org.keycloak.quarkus.runtime.Environment.getCurrentOrCreateFeatureProfile;
Expand Down Expand Up @@ -232,6 +237,28 @@ ProfileBuildItem configureProfile(KeycloakRecorder recorder) {
return new ProfileBuildItem();
}

/**
* Check whether JDBC driver is present for the specified DB
*
* @param ignore used for changing build items execution order with regards to Agroal 8000 Processor
*/
@BuildStep(>
@Produce(CheckJdbcBuildStep.class)
void checkJdbcDriver(BuildProducer<JdbcDriverBuildItem> ignore) {
final Optional<String> dbDriver = Configuration.getOptionalValue("quarkus.datasource.jdbc.driver");

if (dbDriver.isPresent()) {
try {
// We do not want to initialize the JDBC driver class
Class.forName(dbDriver.get(), false, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
// Ignore queued TRACE and DEBUG messages for not initialized log handlers
InitialConfigurator.DELAYED_HANDLER.setBuildTimeHandlers(new Handler[]{});
throw new ConfigurationException(String.format("Unable to find the JDBC driver (%s). You need to install it.", dbDriver.get()));
}
}
}

/**
* <p>Configures the persistence unit for Quarkus.
*
Expand Down Expand Up @@ -281,6 +308,7 @@ void configurePersistenceUnits(HibernateOrmConfig config,
}

@BuildStep(>
@Consume(CheckJdbcBuildStep.class)
void produceDefaultPersistenceUnit(BuildProducer<PersistenceXmlDescriptorBuildItem> producer) {
String storage = Configuration.getRawValue(
NS_KEYCLOAK_PREFIX.concat(StorageOptions.STORAGE.getKey()));
Expand Down Expand Up @@ -559,11 +587,13 @@ void index(BuildProducer<IndexDependencyBuildItem> indexDependencyBuildItemBuild
}

@BuildStep( >
@Consume(CheckJdbcBuildStep.class)
void indexNewJpaStore(BuildProducer<IndexDependencyBuildItem> indexDependencyBuildItemBuildProducer) {
indexDependencyBuildItemBuildProducer.produce(new IndexDependencyBuildItem("org.keycloak", "keycloak-model-map-jpa"));
}

@BuildStep(>
@Consume(CheckJdbcBuildStep.class)
void indexLegacyJpaStore(BuildProducer<IndexDependencyBuildItem> indexDependencyBuildItemBuildProducer) {
indexDependencyBuildItemBuildProducer.produce(new IndexDependencyBuildItem("org.keycloak", "keycloak-model-jpa"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMIZED_BUILD_OPTION_LONG;

import org.junit.jupiter.api.Test;
import org.keycloak.config.database.Database;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.it.junit5.extension.DistributionTest;

Expand Down Expand Up @@ -76,4 +77,23 @@ void testDoNotRecordRuntimeOptionsDuringBuild(KeycloakDistribution distribution)
CLIResult result = distribution.run("start", "--hostname=mykeycloak", OPTIMIZED_BUILD_OPTION_LONG);
result.assertMessage("Key material not provided to setup HTTPS");
}

@Test
@RawDistOnly(reason = "Containers are immutable")
@Launch({"build", "--db=oracle"})
void missingOracleJdbcDriver(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;

String dbDriver = Database.getDriver("oracle", true).orElse("");
String errorMessage = String.format("ERROR: Unable to find the JDBC driver (%s). You need to install it.", dbDriver);

boolean isProduct = System.getProperty("product") != null;
if (isProduct) {
cliResult.assertError(errorMessage);
cliResult.assertNoBuild();
} else {
cliResult.assertNoMessage(errorMessage);
cliResult.assertBuild();
}
}
}
0