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),