From a1295397ec76fbf3bfb47fcaaed4857a2bd1e813 Mon Sep 17 00:00:00 2001 From: Steve Hawkins Date: Wed, 13 May 2026 13:05:36 -0400 Subject: [PATCH] fix: further rationalizing how we are creating temporary files closes: #48566 Signed-off-by: Steve Hawkins --- .../jaxrs/QuarkusKeycloakApplication.java | 4 ++-- .../src/main/java/org/keycloak/Keycloak.java | 10 +++++---- .../GzipResourceEncodingProviderFactory.java | 5 +++-- .../resources/KeycloakApplication.java | 18 ++++++++------- .../resteasy/ResteasyKeycloakApplication.java | 2 +- testsuite/utils/pom.xml | 7 +++++- .../keycloak/testsuite/KeycloakServer.java | 22 ++----------------- 7 files changed, 30 insertions(+), 38 deletions(-) diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/jaxrs/QuarkusKeycloakApplication.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/jaxrs/QuarkusKeycloakApplication.java index 52eacf8477a2..68a64383864c 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/jaxrs/QuarkusKeycloakApplication.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/jaxrs/QuarkusKeycloakApplication.java @@ -63,8 +63,8 @@ public class QuarkusKeycloakApplication extends KeycloakApplication { @Override protected String getDataDir() { return Environment.getDataDir().orElseGet(() -> { - logger.warnf("%s is not set, the system temporary directory will be used as the Keycloak data directory.", Environment.KC_HOME_DIR); - return System.getProperty("java.io.tmpdir"); + logger.warnf("%s is not set", Environment.KC_HOME_DIR); + return null; }); } diff --git a/quarkus/tests/junit5/src/main/java/org/keycloak/Keycloak.java b/quarkus/tests/junit5/src/main/java/org/keycloak/Keycloak.java index 63c9f29d49f8..1d887d8cc026 100644 --- a/quarkus/tests/junit5/src/main/java/org/keycloak/Keycloak.java +++ b/quarkus/tests/junit5/src/main/java/org/keycloak/Keycloak.java @@ -364,18 +364,20 @@ public static Path initTempDirectory(String name) { String buildDir = System.getProperty("project.build.directory"); if (buildDir == null) { try { - return Files.createTempDirectory(name).toAbsolutePath(); + Path tempDirectory = Files.createTempDirectory(name); + tempDirectory.toFile().deleteOnExit(); + return tempDirectory.toAbsolutePath(); } catch (IOException e) { throw new RuntimeException("Could not create temporary directory", e); } } else { - Path homeDir = Path.of(buildDir, name); + Path tempDirectory = Path.of(buildDir, name); try { - FileUtils.deleteDirectory(homeDir.toFile()); + FileUtils.deleteDirectory(tempDirectory.toFile()); } catch (IOException e) { e.printStackTrace(); } - return homeDir; + return tempDirectory; } } diff --git a/services/src/main/java/org/keycloak/encoding/GzipResourceEncodingProviderFactory.java b/services/src/main/java/org/keycloak/encoding/GzipResourceEncodingProviderFactory.java index 2d432db1a160..39e80691d57f 100644 --- a/services/src/main/java/org/keycloak/encoding/GzipResourceEncodingProviderFactory.java +++ b/services/src/main/java/org/keycloak/encoding/GzipResourceEncodingProviderFactory.java @@ -82,8 +82,9 @@ private synchronized File initCacheDir() { } } - if (!cacheDir.isDirectory() && !cacheDir.mkdirs()) { - logger.warn("Failed to create gzip cache directory"); + cacheDir.mkdirs(); + if (!cacheDir.isDirectory()) { + logger.warn("Failed to create gzip cache directory " + cacheDir.getAbsolutePath()); return null; } diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java index 38063fde8535..10744bcc3f0b 100644 --- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java +++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java @@ -19,6 +19,7 @@ import java.io.File; import java.time.Duration; import java.time.Instant; +import java.util.Optional; import java.util.concurrent.TimeUnit; import jakarta.ws.rs.core.Application; @@ -52,20 +53,21 @@ public abstract class KeycloakApplication extends Application { private static volatile DefaultKeycloakSessionFactory sessionFactory; + /** + * Get the temp directory as initialized by the current KeycloakApplication. + *
+ * The directory is not guaranteed to exist + */ public static String getTmpDirectory() { - return System.getProperty(KC_TMPDIR, System.getProperty("java.io.tmpdir")); + return Optional.ofNullable(System.getProperty(KC_TMPDIR)).orElseThrow(() -> new RuntimeException("No temporary directory was configured.")); } protected void initTmpDirectory() { String dataDir = getDataDir(); - File tmpDir = new File(dataDir, "tmp"); - tmpDir.mkdirs(); - if (tmpDir.isDirectory()) { - logger.debugf("Using server tmp directory: %s", tmpDir.getAbsolutePath()); - } else { - logger.warnf("Temporary directory %s does not exist and it was not possible to create it.", tmpDir.getAbsolutePath()); + if (dataDir != null) { + File tmpDir = new File(dataDir, "tmp"); + System.setProperty(KC_TMPDIR, tmpDir.getAbsolutePath()); } - System.setProperty(KC_TMPDIR, tmpDir.getAbsolutePath()); } protected abstract String getDataDir(); diff --git a/services/src/test/java/org/keycloak/services/resteasy/ResteasyKeycloakApplication.java b/services/src/test/java/org/keycloak/services/resteasy/ResteasyKeycloakApplication.java index 436b27020742..9c9766733084 100644 --- a/services/src/test/java/org/keycloak/services/resteasy/ResteasyKeycloakApplication.java +++ b/services/src/test/java/org/keycloak/services/resteasy/ResteasyKeycloakApplication.java @@ -79,7 +79,7 @@ public ResteasyKeycloakApplication() { @Override protected String getDataDir() { - return System.getProperty("project.build.directory"); + return System.getProperty("jboss.server.data.dir"); } @Override diff --git a/testsuite/utils/pom.xml b/testsuite/utils/pom.xml index ebdd668df73d..89ccd96a12a8 100755 --- a/testsuite/utils/pom.xml +++ b/testsuite/utils/pom.xml @@ -267,7 +267,12 @@ mssql-jdbc ${mssql-jdbc.version} - + + + org.keycloak + keycloak-junit5 + + io.quarkus quarkus-micrometer diff --git a/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java b/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java index 3a600cbcbcde..32e9338bf45d 100755 --- a/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java +++ b/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java @@ -22,7 +22,6 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.security.KeyStore; import java.text.SimpleDateFormat; @@ -33,7 +32,6 @@ import java.util.Map; import java.util.Properties; import java.util.function.Function; -import java.util.stream.Stream; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; @@ -43,6 +41,7 @@ import jakarta.servlet.DispatcherType; import jakarta.servlet.Filter; +import org.keycloak.Keycloak; import org.keycloak.authentication.AuthenticatorSpi; import org.keycloak.authentication.authenticators.browser.DeployedScriptAuthenticatorFactory; import org.keycloak.authorization.policy.provider.PolicySpi; @@ -321,24 +320,7 @@ public static String detectDataDirectory() { } // we generate a dynamic jboss.server.data.dir and remove it at the end. - try { - String tempKeycloakFolder = KeycloakApplication.getTmpDirectory(); - File tmpDataDir = new File(tempKeycloakFolder, "/data"); - - if (tmpDataDir.mkdirs()) { - tmpDataDir.deleteOnExit(); - } else try (Stream dir = Files.list(tmpDataDir.toPath())) { - if (dir.findAny().isPresent()) { // Works well if directory is empty - throw new IOException("Could not create directory " + tmpDataDir); - } - } - - dataPath = tmpDataDir.getAbsolutePath(); - } catch (IOException ioe){ - throw new RuntimeException("Could not create temporary " + JBOSS_SERVER_DATA_DIR, ioe); - } - - return dataPath; + return Keycloak.initTempDirectory("keycloak-data").toFile().getAbsolutePath(); } private KeycloakServerConfig config;