{"id":"e48523a9b6454f07","repo":"spring-projects/spring-boot","slug":"main-class-name-has-not-been-configured-and-it-cou","errorCode":null,"errorMessage":"Main class name has not been configured and it could not be resolved from classpath {}","messagePattern":"Main class name has not been configured and it could not be resolved from classpath (.+?)","errorType":"validation","errorClass":"InvalidUserDataException","httpStatus":null,"severity":"error","filePath":"build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/ResolveMainClassName.java","lineNumber":175,"sourceCode":"\t\t\t.getFiles()\n\t\t\t.stream()\n\t\t\t.map(File::getAbsolutePath)\n\t\t\t.collect(Collectors.joining(File.pathSeparator));\n\t\treturn this.outputFile.map(new ClassNameReader(classpath));\n\t}\n\n\tprivate static final class ClassNameReader implements Transformer<String, RegularFile> {\n\n\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":157,"sourceCodeEnd":191,"githubUrl":"https://github.com/spring-projects/spring-boot/blob/5b2dbdbb8be64415eb6552f81ff7c449c8d251e6/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/ResolveMainClassName.java#L157-L191","documentation":"Thrown by ResolveMainClassName.ClassNameReader.transform() when the output file produced by resolveMainClassName() is empty, meaning no main class was found on any classpath directory and the user did not configure one. It is raised as an InvalidUserDataException only when the main-class name provider is actually read (lazy), typically when bootJar/bootRun/bootWar or bootBuildImage resolves it.","triggerScenarios":"resolveAndStoreMainClassName() writes an empty string to outputFile because resolveMainClassName() found no @SpringBootApplication/main class; later readMainClassName()'s ClassNameReader sees file.getAsFile().length()==0 and throws at line 175, embedding the joined classpath directories in the message.","commonSituations":"Library-only modules with no main class; the main class lives in a source set not wired into the boot classpath; classes are in a jar but the task only scans directories (filter(File::isDirectory)); main source set output dir is empty because compileJava did not run; multi-module setup where the application module was not the one applying the plugin.","solutions":["Explicitly set the main class: tasks.named('bootJar') { mainClass.set('com.example.MyApp') } or springBoot { mainClass.set('com.example.MyApp') }.","Ensure your @SpringBootApplication-annotated class is compiled into the main source set's output directory before bootJar/resolveMainClassName runs.","If this is a library module, remove the Spring Boot application plugin so main-class resolution is not attempted.","Run with --info to see which classpath directories were scanned and confirm they contain your classes."],"exampleFix":"// before: no main class configured, resolution fails\ntasks.named('bootJar') {\n    // relies on classpath scan that finds nothing\n}\n// after: declare the main class explicitly\ntasks.named('bootJar') {\n    mainClass.set('com.example.MyApplication')\n}\n","handlingStrategy":"validation","validationCode":"// Configure mainClass explicitly, or assert a main class exists before bootJar\nimport java.io.File\n\nfun hasApplicationClass(sourceDir: File, fqcn: String): Boolean {\n    val rel = fqcn.replace('.', '/') + \".class\"\n    return File(sourceDir, rel).exists()\n}\n\n// usage in build.gradle.kts\nval mainSource = sourceSets.main.get().output.classesDirs.singleFile\ntasks.named(\"bootJar\") {\n    if (!hasApplicationClass(mainSource, \"com.example.MyApplication\")) {\n        throw GradleException(\"Main class missing; set tasks.bootJar.mainClass\")\n    }\n    mainClass.set(\"com.example.MyApplication\")\n}\n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set mainClass explicitly for application modules (springBoot { mainClass.set(...) }).","Do not apply the Spring Boot application plugin to library modules that have no main class.","Ensure compileJava produces classes before bootJar by respecting task dependencies."],"tags":["gradle","main-class","configuration","boot-jar","application-plugin"],"analyzedSha":"5b2dbdbb8be64415eb6552f81ff7c449c8d251e6","analyzedAt":"2026-08-04T18:53:14.967Z","schemaVersion":2}