{"record":{"id":"3d5cdfb97d0ef678","repo":"spring-projects/spring-boot","slug":"failed-to-get-file-mode-from-copyspec","errorCode":null,"errorMessage":"Failed to get file mode from CopySpec","messagePattern":"Failed to get file mode from CopySpec","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java","lineNumber":167,"sourceCode":"\tprivate @Nullable Integer asUnixNumeric(Property<ConfigurableFilePermissions> permissions) {\n\t\treturn permissions.isPresent() ? permissions.get().toUnixNumeric() : null;\n\t}\n\n\tprivate @Nullable Integer getDirMode(CopySpec copySpec) {\n\t\ttry {\n\t\t\treturn (Integer) copySpec.getClass().getMethod(\"getDirMode\").invoke(copySpec);\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthrow new RuntimeException(\"Failed to get dir mode from CopySpec\", ex);\n\t\t}\n\t}\n\n\tprivate @Nullable Integer getFileMode(CopySpec copySpec) {\n\t\ttry {\n\t\t\treturn (Integer) copySpec.getClass().getMethod(\"getFileMode\").invoke(copySpec);\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthrow new RuntimeException(\"Failed to get file mode from CopySpec\", ex);\n\t\t}\n\t}\n\n\tprivate boolean isUsingDefaultLoader(Jar jar) {\n\t\treturn DEFAULT_LAUNCHER_CLASSES.contains(jar.getManifest().getAttributes().get(\"Main-Class\"));\n\t}\n\n\tvoid requiresUnpack(String... patterns) {\n\t\tthis.requiresUnpack.include(patterns);\n\t}\n\n\tvoid requiresUnpack(Spec<FileTreeElement> spec) {\n\t\tthis.requiresUnpack.include(spec);\n\t}\n\n\tvoid excludeNonZipLibraryFiles(FileCopyDetails details) {\n\t\tif (this.librarySpec.isSatisfiedBy(details)) {\n\t\t\texcludeNonZipFiles(details);","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/spring-projects/spring-boot/blob/270dfe353fb830fd69b823a8a859287ff103854b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java#L149-L185","documentation":"Thrown by BootArchiveSupport.getFileMode, the reflective counterpart to getDirMode. It invokes CopySpec.getFileMode() via reflection on the legacy path (Gradle < 8.3). The caller selects between the modern Property<ConfigurableFilePermissions> API (asUnixNumeric) and this reflective fallback based on the Gradle version. Any reflection exception is wrapped and rethrown.","triggerScenarios":"Building a boot archive on Gradle < 8.3 where CopySpec lacks a getFileMode() method or the method throws during invocation. The caller first tries asUnixNumeric(copySpec.getFilePermissions()); if that path is not taken, it falls through to getFileMode(copySpec).","commonSituations":"Identical root causes to getDirMode failures: old Gradle version, custom CopySpec subclass, or a Gradle distribution where the method was removed. Often co-occurs with error [5].","solutions":["Upgrade Gradle to 8.3+ to use filePermissions().toUnixNumeric() directly.","Ensure no custom plugin is replacing or wrapping the CopySpec type used by bootJar/bootWar.","Downgrade the Spring Boot plugin to match an old Gradle if upgrade is impossible."],"exampleFix":"// before: Gradle 7.x\n// after: upgrade to Gradle 8.14+\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.14.2-bin.zip","handlingStrategy":"validation","validationCode":"// Ensure Gradle 8.3+ before boot archive tasks.\nif (GradleVersion.current().compareTo(GradleVersion.version(\"8.3\")) < 0) {\n    throw new GradleException(\"Upgrade to Gradle 8.3+ to avoid reflective getFileMode.\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize on Gradle 8.3+ via the wrapper.","Do not introduce custom CopySpec subclasses into boot archive builds.","Align Spring Boot plugin version with the Gradle version per the compatibility matrix."],"tags":["gradle","reflection","file-permissions","version-compat","boot-archive","copy-spec"],"backgroundTag":null,"analyzedSha":"270dfe353fb830fd69b823a8a859287ff103854b","analyzedAt":"2026-08-11T19:42:06.541Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}