This is an automated email from the ASF dual-hosted git repository.

yuqi1129 pushed a commit to branch fix-mkdirs-toctou
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/fix-mkdirs-toctou by this push:
     new afa79a7e57 [#11940] Address directory creation review comments
afa79a7e57 is described below

commit afa79a7e57c5bb8edd93f4590d4397b8d59c6772
Author: yuqi <[email protected]>
AuthorDate: Wed Jul 8 17:04:39 2026 +0800

    [#11940] Address directory creation review comments
---
 .../catalog/hadoop/auth/KerberosAuthUtils.java     |  4 +-
 .../org/apache/gravitino/utils/DirectoryUtils.java | 47 -----------
 .../apache/gravitino/utils/TestDirectoryUtils.java | 94 ----------------------
 .../java/org/apache/gravitino/job/JobManager.java  |  6 +-
 4 files changed, 5 insertions(+), 146 deletions(-)

diff --git 
a/catalogs/hadoop-auth/src/main/java/org/apache/gravitino/catalog/hadoop/auth/KerberosAuthUtils.java
 
b/catalogs/hadoop-auth/src/main/java/org/apache/gravitino/catalog/hadoop/auth/KerberosAuthUtils.java
index 2375b070ce..eefb05aa05 100644
--- 
a/catalogs/hadoop-auth/src/main/java/org/apache/gravitino/catalog/hadoop/auth/KerberosAuthUtils.java
+++ 
b/catalogs/hadoop-auth/src/main/java/org/apache/gravitino/catalog/hadoop/auth/KerberosAuthUtils.java
@@ -24,13 +24,13 @@ import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import javax.annotation.Nullable;
-import org.apache.gravitino.utils.DirectoryUtils;
 import org.apache.gravitino.utils.FileFetcher;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.security.UserGroupInformation;
@@ -106,7 +106,7 @@ public final class KerberosAuthUtils {
 
     File parentFile = keytabFile.getParentFile();
     if (parentFile != null) {
-      DirectoryUtils.ensureDirectory(parentFile);
+      Files.createDirectories(parentFile.toPath());
     }
 
     FileFetcher.get().fetchFileFromUri(keytabUri, keytabFile, timeoutSec * 
1000, hadoopConf);
diff --git 
a/common/src/main/java/org/apache/gravitino/utils/DirectoryUtils.java 
b/common/src/main/java/org/apache/gravitino/utils/DirectoryUtils.java
deleted file mode 100644
index da07e27509..0000000000
--- a/common/src/main/java/org/apache/gravitino/utils/DirectoryUtils.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.gravitino.utils;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.Files;
-
-/** Utilities for working with local directories. */
-public class DirectoryUtils {
-
-  private DirectoryUtils() {}
-
-  /**
-   * Ensures that the given directory exists, creating it and any missing 
parent directories if
-   * necessary.
-   *
-   * <p>Unlike {@code File#exists()} followed by {@code File#mkdirs()}, this 
method is safe against
-   * concurrent creation of the same directory: it succeeds if the directory 
already exists or is
-   * created concurrently by another thread or process.
-   *
-   * @param dir the directory to create
-   * @throws FileAlreadyExistsException if the path exists but is not a 
directory
-   * @throws IOException if the directory cannot be created
-   */
-  public static void ensureDirectory(File dir) throws IOException {
-    Files.createDirectories(dir.toPath());
-  }
-}
diff --git 
a/common/src/test/java/org/apache/gravitino/utils/TestDirectoryUtils.java 
b/common/src/test/java/org/apache/gravitino/utils/TestDirectoryUtils.java
deleted file mode 100644
index 4c261e9037..0000000000
--- a/common/src/test/java/org/apache/gravitino/utils/TestDirectoryUtils.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.gravitino.utils;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-
-public class TestDirectoryUtils {
-
-  @TempDir private File tempDir;
-
-  @Test
-  public void testEnsureDirectoryCreatesNestedDirectories() throws IOException 
{
-    File nested = new File(tempDir, "a/b/c");
-
-    DirectoryUtils.ensureDirectory(nested);
-
-    Assertions.assertTrue(nested.isDirectory());
-  }
-
-  @Test
-  public void testEnsureDirectoryIsIdempotent() throws IOException {
-    File dir = new File(tempDir, "existing");
-    Assertions.assertTrue(dir.mkdirs());
-
-    DirectoryUtils.ensureDirectory(dir);
-
-    Assertions.assertTrue(dir.isDirectory());
-  }
-
-  @Test
-  public void testEnsureDirectoryRejectsRegularFile() throws IOException {
-    File file = new File(tempDir, "regular-file");
-    Files.writeString(file.toPath(), "content");
-
-    Assertions.assertThrows(IOException.class, () -> 
DirectoryUtils.ensureDirectory(file));
-  }
-
-  @Test
-  public void testEnsureDirectoryToleratesConcurrentCreation() throws 
Exception {
-    int threads = 4;
-    int iterations = 200;
-    ExecutorService executor = Executors.newFixedThreadPool(threads);
-    try {
-      for (int i = 0; i < iterations; i++) {
-        File dir = new File(tempDir, "race-" + i + "/target");
-        CyclicBarrier barrier = new CyclicBarrier(threads);
-        List<Future<?>> futures = new ArrayList<>(threads);
-        for (int t = 0; t < threads; t++) {
-          futures.add(
-              executor.submit(
-                  () -> {
-                    barrier.await();
-                    DirectoryUtils.ensureDirectory(dir);
-                    return null;
-                  }));
-        }
-        for (Future<?> future : futures) {
-          future.get();
-        }
-        Assertions.assertTrue(dir.isDirectory());
-      }
-    } finally {
-      executor.shutdownNow();
-    }
-  }
-}
diff --git a/core/src/main/java/org/apache/gravitino/job/JobManager.java 
b/core/src/main/java/org/apache/gravitino/job/JobManager.java
index b257e87c28..efa24d70ea 100644
--- a/core/src/main/java/org/apache/gravitino/job/JobManager.java
+++ b/core/src/main/java/org/apache/gravitino/job/JobManager.java
@@ -26,6 +26,7 @@ import com.google.common.base.Preconditions;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
+import java.nio.file.Files;
 import java.time.Instant;
 import java.util.Arrays;
 import java.util.List;
@@ -60,7 +61,6 @@ import org.apache.gravitino.meta.JobEntity;
 import org.apache.gravitino.meta.JobTemplateEntity;
 import org.apache.gravitino.metalake.MetalakeManager;
 import org.apache.gravitino.storage.IdGenerator;
-import org.apache.gravitino.utils.DirectoryUtils;
 import org.apache.gravitino.utils.FileFetcher;
 import org.apache.gravitino.utils.NameIdentifierUtil;
 import org.apache.gravitino.utils.NamespaceUtil;
@@ -128,7 +128,7 @@ public class JobManager implements JobOperationDispatcher {
       }
     } else {
       try {
-        DirectoryUtils.ensureDirectory(stagingDir);
+        Files.createDirectories(stagingDir.toPath());
       } catch (IOException e) {
         throw new IllegalArgumentException(
             String.format("Failed to create staging directory %s", 
stagingDirPath), e);
@@ -432,7 +432,7 @@ public class JobManager implements JobOperationDispatcher {
             + String.format(JOB_STAGING_DIR, metalake, jobTemplateName, jobId);
     File jobStagingDir = new File(jobStagingPath);
     try {
-      DirectoryUtils.ensureDirectory(jobStagingDir);
+      Files.createDirectories(jobStagingDir.toPath());
     } catch (IOException e) {
       throw new RuntimeException(
           String.format("Failed to create staging directory %s for job %s", 
jobStagingDir, jobId),

Reply via email to