spring-projects/spring-boot · error · RuntimeException

Failed to get mode from FileCopyDetails

Error message

Failed to get mode from FileCopyDetails

What it means

Thrown by BootZipCopyAction.Processor.getMode() when reflective invocation of FileCopyDetails.getMode() fails. This fallback is selected only on Gradle < 8.3; on 8.3+ details.getPermissions().toUnixNumeric() is used. With the plugin's 8.14 floor this branch is unreachable in normal operation.

Source

Thrown at build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java:485

			return (BootZipCopyAction.this.dirMode != null) ? BootZipCopyAction.this.dirMode : getPermissions(details);
		}

		private int getFileMode(FileCopyDetails details) {
			return (BootZipCopyAction.this.fileMode != null) ? BootZipCopyAction.this.fileMode
					: getPermissions(details);
		}

		private int getPermissions(FileCopyDetails details) {
			return (GradleVersion.current().compareTo(GradleVersion.version("8.3")) >= 0)
					? details.getPermissions().toUnixNumeric() : getMode(details);
		}

		private int getMode(FileCopyDetails details) {
			try {
				return (int) details.getClass().getMethod("getMode").invoke(details);
			}
			catch (Exception ex) {
				throw new RuntimeException("Failed to get mode from FileCopyDetails", ex);
			}
		}

	}

	/**
	 * Callback interface used to customize a {@link ZipArchiveEntry}.
	 */
	@FunctionalInterface
	private interface ZipEntryCustomizer {

		ZipEntryCustomizer NONE = (entry) -> {
		};

		/**
		 * Customize the entry.
		 * @param entry the entry to customize
		 * @throws IOException on IO error

View on GitHub (pinned to 5b2dbdbb8b)

Solutions

  1. Upgrade Gradle to 8.14 or later so the modern getPermissions() path is used.
  2. Ensure inputs are produced by standard Gradle copy sources (not custom FileCopyDetails).
  3. Verify the JVM is not applying restrictive module access flags to Gradle internals.

Example fix

// gradle/wrapper/gradle-wrapper.properties
// before:
//   distributionUrl=...gradle-8.2-bin.zip
// after:
//   distributionUrl=...gradle-8.14-bin.zip
Defensive patterns

Strategy: validation

Validate before calling

import org.gradle.util.GradleVersion
require(GradleVersion.current() >= GradleVersion.version("8.3")) {
    "FileCopyDetails.getPermissions() requires Gradle 8.3+ (use 8.14+)"
}

Prevention

When it happens

Trigger: getPermissions(details) routes to getMode(details) when GradleVersion.current() < 8.3; details.getClass().getMethod('getMode').invoke(details) throws, wrapped as RuntimeException at line 485.

Common situations: Unsupported old Gradle; a custom FileCopyDetails implementation lacking getMode; module restrictions blocking reflection.

Related errors


AI-assisted analysis of spring-projects/spring-boot@5b2dbdbb8b (2026-08-04). Data as JSON: /data/errors/a92f5afc04e2fbd9.json. Report an issue: GitHub.