{"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/5b2dbdbb8be64415eb6552f81ff7c449c8d251e6/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java#L149-L185","documentation":"Thrown by BootArchiveSupport.getFileMode() when reflective invocation of CopySpec.getFileMode() fails. Like getDirMode(), this fallback is only selected on Gradle < 8.3; on 8.3+ getFilePermissions().toUnixNumeric() is used. With the plugin's 8.14 floor this branch should not be hit in normal operation.","triggerScenarios":"getUnixNumericFilePermissions() routes to getFileMode() when GradleVersion.current() < 8.3; the reflective getMethod(\"getFileMode\").invoke(copySpec) throws, wrapped as RuntimeException at line 167.","commonSituations":"Unsupported old Gradle; custom CopySpec without getFileMode; reflective access blocked by JVM security/module settings.","solutions":["Upgrade Gradle to 8.14 or later.","Confirm the CopySpec used by bootJar/bootWar is a standard Gradle CopySpec.","Check that no JVM --illegal-access or module flags block reflection on Gradle classes."],"exampleFix":"// gradle/wrapper/gradle-wrapper.properties\n// before:\n//   distributionUrl=...gradle-8.2-bin.zip\n// after:\n//   distributionUrl=...gradle-8.14-bin.zip\n","handlingStrategy":"validation","validationCode":"import org.gradle.util.GradleVersion\nrequire(GradleVersion.current() >= GradleVersion.version(\"8.3\")) {\n    \"Boot archive file mode requires Gradle 8.3+ (use 8.14+)\"\n}\n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use Gradle 8.14+ so the filePermissions path is selected.","Ensure CopySpec instances are standard Gradle implementations."],"tags":["gradle","version-compat","reflection","file-permissions","boot-archive"],"analyzedSha":"5b2dbdbb8be64415eb6552f81ff7c449c8d251e6","analyzedAt":"2026-08-04T18:53:14.967Z","schemaVersion":2}