Skip to content

Commit 2f1fde5

Browse files
committed
[SPARK-53137][CORE][SQL] Support forceDeleteOnExit in SparkFileUtils and JavaUtils
### What changes were proposed in this pull request? This PR aims to support `forceDeleteOnExit` in `SparkFileUtils` and `JavaUtils`. ### Why are the changes needed? To improve Spark's file utility functions. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Pass the CIs. ### Was this patch authored or co-authored using generative AI tooling? No. Closes #51866 from dongjoon-hyun/SPARK-53137. Authored-by: Dongjoon Hyun <[email protected]> Signed-off-by: Dongjoon Hyun <[email protected]>
1 parent bca5f3a commit 2f1fde5

File tree

5 files changed

+41
-2
lines changed

5 files changed

+41
-2
lines changed

common/utils/src/main/java/org/apache/spark/network/util/JavaUtils.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,31 @@ public static void deleteQuietly(File file) {
7878
}
7979
}
8080

81+
/** Registers the file or directory for deletion when the JVM exists. */
82+
public static void forceDeleteOnExit(File file) throws IOException {
83+
if (file != null && file.exists()) {
84+
if (!file.isDirectory()) {
85+
file.deleteOnExit();
86+
} else {
87+
Path path = file.toPath();
88+
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
89+
@Override
90+
public FileVisitResult preVisitDirectory(Path p, BasicFileAttributes a)
91+
throws IOException {
92+
p.toFile().deleteOnExit();
93+
return a.isSymbolicLink() ? FileVisitResult.SKIP_SUBTREE : FileVisitResult.CONTINUE;
94+
}
95+
96+
@Override
97+
public FileVisitResult visitFile(Path p, BasicFileAttributes a) throws IOException {
98+
p.toFile().deleteOnExit();
99+
return FileVisitResult.CONTINUE;
100+
}
101+
});
102+
}
103+
}
104+
}
105+
81106
/** Move a file from src to dst. */
82107
public static void moveFile(File src, File dst) throws IOException {
83108
if (src == null || dst == null || !src.exists() || src.isDirectory() || dst.exists()) {

common/utils/src/main/scala/org/apache/spark/util/SparkFileUtils.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ private[spark] trait SparkFileUtils extends Logging {
153153
JavaUtils.deleteQuietly(file)
154154
}
155155

156+
/** Registers the file or directory for deletion when the JVM exists. */
157+
def forceDeleteOnExit(file: File): Unit = {
158+
JavaUtils.forceDeleteOnExit(file)
159+
}
160+
156161
def getFile(names: String*): File = {
157162
require(names != null && names.forall(_ != null))
158163
names.tail.foldLeft(Path.of(names.head)) { (path, part) =>

dev/checkstyle.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@
215215
<property name="format" value="FileUtils\.forceDelete\("/>
216216
<property name="message" value="Use deleteRecursively of JavaUtils/SparkFileUtils/Utils instead." />
217217
</module>
218+
<module name="RegexpSinglelineJava">
219+
<property name="format" value="FileUtils\.forceDeleteOnExit\("/>
220+
<property name="message" value="Use forceDeleteOnExit of JavaUtils/SparkFileUtils/Utils instead." />
221+
</module>
218222
<module name="RegexpSinglelineJava">
219223
<property name="format" value="FileUtils\.deleteQuietly"/>
220224
<property name="message" value="Use deleteQuietly of JavaUtils/SparkFileUtils/Utils instead." />

scalastyle-config.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,11 @@ This file is divided into 3 sections:
322322
<customMessage>Use deleteRecursively of JavaUtils/SparkFileUtils/Utils</customMessage>
323323
</check>
324324

325+
<check customId="forceDeleteOnExit" level="error" class="org.scalastyle.file.RegexChecker" enabled="true">
326+
<parameters><parameter name="regex">\bFileUtils\.forceDeleteOnExit\b</parameter></parameters>
327+
<customMessage>Use forceDeleteOnExit of JavaUtils/SparkFileUtils/Utils instead.</customMessage>
328+
</check>
329+
325330
<check customId="deleteQuietly" level="error" class="org.scalastyle.file.RegexChecker" enabled="true">
326331
<parameters><parameter name="regex">\bFileUtils\.deleteQuietly\b</parameter></parameters>
327332
<customMessage>Use deleteQuietly of JavaUtils/SparkFileUtils/Utils</customMessage>

sql/hive-thriftserver/src/main/java/org/apache/hive/service/cli/session/SessionManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import java.util.concurrent.ThreadPoolExecutor;
2929
import java.util.concurrent.TimeUnit;
3030

31-
import org.apache.commons.io.FileUtils;
3231
import org.apache.hadoop.hive.conf.HiveConf;
3332
import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
3433
import org.apache.hive.service.CompositeService;
@@ -43,6 +42,7 @@
4342
import org.apache.spark.internal.SparkLoggerFactory;
4443
import org.apache.spark.internal.LogKeys;
4544
import org.apache.spark.internal.MDC;
45+
import org.apache.spark.network.util.JavaUtils;
4646
import org.apache.spark.util.Utils;
4747

4848
/**
@@ -138,7 +138,7 @@ private void initOperationLogRootDir() {
138138
LOG.info("Operation log root directory is created: {}",
139139
MDC.of(LogKeys.PATH, operationLogRootDir.getAbsolutePath()));
140140
try {
141-
FileUtils.forceDeleteOnExit(operationLogRootDir);
141+
JavaUtils.forceDeleteOnExit(operationLogRootDir);
142142
} catch (IOException e) {
143143
LOG.warn("Failed to schedule cleanup HS2 operation logging root dir: {}", e,
144144
MDC.of(LogKeys.PATH, operationLogRootDir.getAbsolutePath()));

0 commit comments

Comments
 (0)