fix: allow the same vm to run a keycloak instance multiple times (#45936)

closes: #45921

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
Steven Hawkins 2026-02-02 11:00:58 -05:00 committed by GitHub
parent 6e408dd7bc
commit a2e2634940
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 14 deletions

View file

@ -18,17 +18,21 @@
package org.keycloak.quarkus.runtime;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ForkJoinPool;
import jakarta.enterprise.context.ApplicationScoped;
import org.keycloak.common.Profile;
import org.keycloak.common.Version;
import org.keycloak.infinispan.util.InfinispanUtils;
import org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler;
import org.keycloak.quarkus.runtime.cli.Picocli;
import org.keycloak.quarkus.runtime.cli.command.AbstractNonServerCommand;
import org.keycloak.quarkus.runtime.cli.command.DryRunMixin;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
import org.keycloak.quarkus.runtime.integration.jaxrs.QuarkusKeycloakApplication;
import io.quarkus.arc.Arc;
@ -77,6 +81,15 @@ public class KeycloakMain implements QuarkusApplication {
main(args, picocli);
}
public static void reset(Properties systemProperties) {
System.setProperties((Properties) systemProperties.clone());
PropertyMappers.reset();
PersistedConfigSource.getInstance().getConfigValueProperties().clear();
Profile.reset();
Configuration.resetConfig();
ExecutionExceptionHandler.resetExceptionTransformers();
}
public static void main(String[] args, Picocli picocli) {
List<String> cliArgs = List.of(args.length == 0 ? new String[] {"-h"} : args);

View file

@ -23,10 +23,8 @@ import java.util.Properties;
import java.util.function.Function;
import org.keycloak.Config;
import org.keycloak.common.Profile;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
import org.keycloak.quarkus.runtime.KeycloakMain;
import io.smallrye.config.ConfigValue;
import io.smallrye.config.ConfigValue.ConfigValueBuilder;
@ -71,17 +69,9 @@ public abstract class AbstractConfigurationTest {
@BeforeClass
public static void resetConfiguration() {
System.setProperties((Properties) SYSTEM_PROPERTIES.clone());
KeycloakMain.reset(SYSTEM_PROPERTIES);
Environment.setHomeDir(Paths.get("src/test/resources/"));
KcEnvConfigSource.ENV_OVERRIDE.clear();
PropertyMappers.reset();
ConfigArgsConfigSource.setCliArgs();
PersistedConfigSource.getInstance().getConfigValueProperties().clear();
Profile.reset();
Configuration.resetConfig();
ExecutionExceptionHandler.resetExceptionTransformers();
}
@After

View file

@ -22,6 +22,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeoutException;
import org.keycloak.common.Version;
@ -32,6 +33,7 @@ import org.keycloak.config.Option;
import org.keycloak.config.SecurityOptions;
import org.keycloak.platform.Platform;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.KeycloakMain;
import org.keycloak.quarkus.runtime.cli.Picocli;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts;
@ -173,6 +175,7 @@ public class Keycloak {
private Path homeDir;
private List<Dependency> dependencies;
private boolean fipsEnabled;
private Properties systemProperties;
public Keycloak() {
this(null, Version.VERSION, List.of(), false);
@ -190,6 +193,7 @@ public class Keycloak {
}
private Keycloak start(List<String> args) {
systemProperties = (Properties) System.getProperties().clone();
QuarkusBootstrap.Builder builder = QuarkusBootstrap.builder()
.setExistingModel(applicationModel)
.setApplicationRoot(applicationModel.getApplicationModule().getModuleDir().toPath())
@ -216,8 +220,15 @@ public class Keycloak {
}
public void stop() throws TimeoutException {
if (isRunning()) {
closeApplication();
try {
if (isRunning()) {
closeApplication();
}
} finally {
if (systemProperties != null) {
KeycloakMain.reset(systemProperties);
systemProperties = null;
}
}
}