{"record":{"id":"6d69a7fdd92c09c6","repo":"spring-projects/spring-boot","slug":"failed-to-read-main-class-name-from","errorCode":null,"errorMessage":"Failed to read main class name from '{}'","messagePattern":"Failed to read main class name from '(.+?)'","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/ResolveMainClassName.java","lineNumber":184,"sourceCode":"\t\tprivate final String classpath;\n\n\t\tprivate ClassNameReader(String classpath) {\n\t\t\tthis.classpath = classpath;\n\t\t}\n\n\t\t@Override\n\t\tpublic String transform(RegularFile file) {\n\t\t\tif (file.getAsFile().length() == 0) {\n\t\t\t\tthrow new InvalidUserDataException(\n\t\t\t\t\t\t\"Main class name has not been configured and it could not be resolved from classpath \"\n\t\t\t\t\t\t\t\t+ this.classpath);\n\t\t\t}\n\t\t\tPath output = file.getAsFile().toPath();\n\t\t\ttry {\n\t\t\t\treturn Files.readString(output);\n\t\t\t}\n\t\t\tcatch (IOException ex) {\n\t\t\t\tthrow new RuntimeException(\"Failed to read main class name from '\" + output + \"'\");\n\t\t\t}\n\t\t}\n\n\t}\n\n}\n","sourceCodeStart":166,"sourceCodeEnd":191,"githubUrl":"https://github.com/spring-projects/spring-boot/blob/270dfe353fb830fd69b823a8a859287ff103854b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/ResolveMainClassName.java#L166-L191","documentation":"Thrown by ResolveMainClassName.ClassNameReader.transform when Files.readString(output) throws an IOException while reading the temp file that holds the resolved main class name. The file is non-empty (it passed the length > 0 check at line 175), so the resolution task did write something, but the read-back failed at the filesystem level.","triggerScenarios":"The main-class resolution file exists and is non-empty, but the JVM cannot read it: the file was deleted between the length check and the readString call, permissions changed, or the underlying filesystem returned an I/O error.","commonSituations":"Running on a flaky network filesystem (NFS, SMB) where temp files become inaccessible. Antivirus or file-watching software locking or deleting the temp file mid-build. Concurrent Gradle daemons or build processes racing on the same build directory. Disk corruption or the build directory being on a RAM disk that ran out of space.","solutions":["Run the build with '--no-daemon' and a clean build directory (gradle clean) to rule out daemon/process races.","Move the Gradle build temporary directory to a stable local filesystem: set 'org.gradle.java.io.tmpdir' or GRADLE_OPTS.","Disable or whitelist the build directory in antivirus/file-watcher tools.","Check disk space and filesystem health if the error is persistent."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before reading, confirm the file is still readable.\nPath output = file.getAsFile().toPath();\nif (!Files.isReadable(output)) {\n    // re-trigger resolution or fail with a clearer message\n    throw new IllegalStateException(\"Main class file not readable: \" + output);\n}","typeGuard":null,"tryCatchPattern":"// Retry once on transient IOException, then surface a clear error.\nString mainClass = null;\nfor (int attempt = 0; attempt < 2; attempt++) {\n    try {\n        mainClass = Files.readString(output);\n        break;\n    } catch (IOException ex) {\n        if (attempt == 1) throw new RuntimeException(\"Main class file unreadable after retry: \" + output, ex);\n    }\n}","preventionTips":["Build on a stable local filesystem, not a network mount.","Run 'gradle clean' between heavy builds to avoid stale temp files.","Whitelist the build directory in antivirus/file-watcher tools."],"tags":["gradle","io","filesystem","main-class","temp-file"],"backgroundTag":null,"analyzedSha":"270dfe353fb830fd69b823a8a859287ff103854b","analyzedAt":"2026-08-11T19:42:06.541Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}