Skip to content

Use FileUtils.moveDirectory to support cross-filesystem moves#343

Merged
reda-alaoui merged 1 commit intoCosium:masterfrom
alphae-nix:fix/tmpfs-directory-move
Feb 28, 2026
Merged

Use FileUtils.moveDirectory to support cross-filesystem moves#343
reda-alaoui merged 1 commit intoCosium:masterfrom
alphae-nix:fix/tmpfs-directory-move

Conversation

@alphae-nix
Copy link
Contributor

Problem

When running tests locally with ./mvnw --batch-mode clean verify, moveFiles() fails with:

java.nio.file.DirectoryNotEmptyException: /tmp/git-code-format-maven-plugin-test3626331939795592289/NonRootModuleTest_GIVEN_bad_formatted_files_WHEN_format_code_THEN_all_files_should_have_correct_format[3.5.0]_non-root-module

	at java.base/sun.nio.fs.UnixFileSystem.ensureEmptyDir(UnixFileSystem.java:797)
	at java.base/sun.nio.fs.UnixFileSystem.move(UnixFileSystem.java:900)
	at java.base/sun.nio.fs.UnixFileSystemProvider.move(UnixFileSystemProvider.java:289)
	at java.base/java.nio.file.Files.move(Files.java:1319)
	at com.cosium.code.format.AbstractTest.moveFiles(AbstractTest.java:148)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)

Root cause

On Ubunut, /tmp is mounted as tmpfs, while the project directory lives on a disk filesystem (ext4, in my case).

Files.move() delegates to UnixFileSystemProvider.move()UnixFileSystem.move()UnixCopyFile.move(), which calls the native method rename. This native method wraps the Linux rename syscall, which fails with cross-device link
error when source and target are on different filesystems. Java handles this fallback for files (copy + delete) with the copyOption, but for non-empty directories it has no recursive fallback it calls ensureEmptyDir() on the source and immediately throws DirectoryNotEmptyException. cf. this comment on Files.move

Why it passes on GitHub Actions and not locally

The repo GitHub Actions Ubuntu runners do not mount /tmp as tmpfs, it is part of the root filesystem. Source and target are on the same filesystem, rename succeeds, and the tests pass. cf this comment

Fix

Replace Files.move() with FileUtils.moveDirectory(), which performs a recursive copy + delete and correctly handles cross-filesystem directory moves

Signed-off-by: Laurent Delatte <ldelatte@cosium.com>
@alphae-nix alphae-nix marked this pull request as ready for review February 28, 2026 16:45
@reda-alaoui reda-alaoui merged commit 3c25e34 into Cosium:master Feb 28, 2026
1 check passed
@alphae-nix alphae-nix deleted the fix/tmpfs-directory-move branch February 28, 2026 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants