quarkusio/quarkus · error · UncheckedIOException

Failed to collect project's classes in a temporary dir

Error message

Failed to collect project's classes in a temporary dir

What it means

QuarkusGradleUtils.mergeClassesDirs copies the project's compiled classes directories into a single merged temporary directory; if any IOException occurs during copying it wraps it in an UncheckedIOException with the message 'Failed to collect project's classes in a temporary dir'. This blocks dev mode because Quarkus needs one merged output directory for the application classes.

Solutions

  1. Check available disk space and write permissions on java.io.tmpdir (or the configured temp location).
  2. Stop duplicate Gradle daemons: ./gradlew --stop, then re-run the dev-mode task.
  3. Set the java.io.tmpdir system property to a writable directory: GRADLE_OPTS=-Djava.io.tmpdir=/path/writable.
  4. Rebuild the project (./gradlew classes) to ensure the classes dirs exist before dev mode.
  5. Exclude the project directory from antivirus/indexing tools that lock files during copying.

Example fix

// before: full or unwritable default temp dir
// after: point Gradle at a writable temp dir
// in gradle.properties or environment
org.gradle.jvmargs=-Djava.io.tmpdir=/home/user/tmp
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check writable temp space before running dev mode
import java.nio.file.*;
Path tmp = Paths.get(System.getProperty("java.io.tmpdir"));
Files.createTempFile("quarkus-check", ".tmp");
if (tmp.toFile().getUsableSpace() < 100_000_000L) {
  throw new IllegalStateException("Insufficient space in " + tmp + "; set -Djava.io.tmpdir");
}

Try / catch

try {
  ./gradlew quarkusDev
} catch (UncheckedIOException e) {
  if (e.getMessage().contains("Failed to collect project's classes")) {
    // free temp space, stop extra daemons (./gradlew --stop), rerun with GRADLE_OPTS=-Djava.io.tmpdir=<writable>
  }
}

Prevention

When it happens

Trigger: Calling QuarkusGradleUtils.mergeClassesDirs (via merged) when creating or copying into the temporary merged-classes dir fails: missing read permissions on source classes dirs, unwritable temp directory, or file locks held by another process.

Common situations: Read-only or full TMPDIR (/tmp full or noexec/quota limits); two Gradle daemons or an IDE build running concurrently and holding file locks; classes directory deleted mid-build by a parallel clean; sandboxed CI environments restricting temp file creation.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/a2d69ad33cd38479. Report an issue: GitHub.

Appendix: source

Thrown at devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGradleUtils.java:76

        try {
            Path mergedClassesDir = tmpDir.toPath().resolve("quarkus-app-classes" + (test ? "-test" : ""));

            if (!populated) {
                return mergedClassesDir;
            }

            if (Files.exists(mergedClassesDir)) {
                IoUtils.recursiveDelete(mergedClassesDir);
            }

            for (Path classesDir : existingClassesDirs) {
                IoUtils.copy(classesDir, mergedClassesDir);
            }

            return mergedClassesDir;
        } catch (IOException e) {
            throw new UncheckedIOException(ERROR_COLLECTING_PROJECT_CLASSES, e);
        }
    }

}

View on GitHub (pinned to e1c734241f)