{"record":{"id":"fdbbce03f8083c68","repo":"gradle/gradle","slug":"could-not-read-annotation-processor-declarations-f-fdbbce","errorCode":null,"errorMessage":"Could not read annotation processor declarations from {}. Gradle will assume that this directory contains no annotation processors.","messagePattern":"Could not read annotation processor declarations from (.+?)\\. Gradle will assume that this directory contains no annotation processors\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"platforms/jvm/language-java/src/main/java/org/gradle/api/internal/tasks/compile/processing/AnnotationProcessorDetector.java","lineNumber":109,"sourceCode":"                return detectProcessorsInClassesDir(file);\n            } else if (FileUtils.hasExtensionIgnoresCase(file.getName(), \".jar\")) {\n                return detectProcessorsInJar(file);\n            }\n            return Collections.emptyList();\n        }\n\n        private List<AnnotationProcessorDeclaration> detectProcessorsInClassesDir(File classesDir) {\n            try {\n                List<String> processorClassNames = getProcessorClassNames(classesDir);\n                try {\n                    Map<String, IncrementalAnnotationProcessorType> processorTypes = getProcessorTypes(classesDir);\n                    return toProcessorDeclarations(processorClassNames, processorTypes);\n                } catch (Exception e) {\n                    logger.warn(\"Could not read annotation processor declarations from \" + classesDir + \". Gradle will assume that all processors in this directory are non-incremental.\", logStackTraces ? e : null);\n                    return toProcessorDeclarations(processorClassNames, Collections.emptyMap());\n                }\n            } catch (Exception e) {\n                logger.warn(\"Could not read annotation processor declarations from \" + classesDir + \". Gradle will assume that this directory contains no annotation processors.\", logStackTraces ? e : null);\n                return Collections.emptyList();\n            }\n        }\n\n        private List<String> getProcessorClassNames(File classesDir) throws IOException {\n            File processorDeclaration = new File(classesDir, PROCESSOR_DECLARATION);\n            if (!processorDeclaration.isFile()) {\n                return Collections.emptyList();\n            }\n            return readLines(processorDeclaration);\n        }\n\n        private Map<String, IncrementalAnnotationProcessorType> getProcessorTypes(File classesDir) throws IOException {\n            File incrementalProcessorDeclaration = new File(classesDir, INCREMENTAL_PROCESSOR_DECLARATION);\n            if (!incrementalProcessorDeclaration.isFile()) {\n                return Collections.emptyMap();\n            }\n            List<String> lines = readLines(incrementalProcessorDeclaration);","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/gradle/gradle/blob/534f27719b66953f95cc907aae7f2c1b12f5482d/platforms/jvm/language-java/src/main/java/org/gradle/api/internal/tasks/compile/processing/AnnotationProcessorDetector.java#L91-L127","documentation":"While scanning a classes directory for annotation processors, Gradle first reads META-INF/services/javax.annotation.processing.Processor (PROCESSOR_DECLARATION). If that read fails (getProcessorClassNames throws - I/O error, unreadable/corrupt declaration), Gradle assumes the directory contains NO annotation processors and returns an empty list. javac still discovers processors itself at execution time, but Gradle's incremental-processing bookkeeping for this directory is lost.","triggerScenarios":"The outer catch fires because reading the processor declaration from the classes dir throws: permission problems, concurrent truncation of the directory while Gradle scans it, or a malformed/encoding-broken declaration file.","commonSituations":"Classes dirs mutated by a concurrent build or file sync (Docker/rsync) during scanning; antivirus or permissions blocking reads on Windows; corrupted build outputs after a killed daemon or interrupted build.","solutions":["Run with --stacktrace to see the underlying exception and identify the failing file","Clean and rebuild the project that produces the classes directory","Check filesystem permissions and antivirus exclusions on the build output directory","If the dir comes from another build tool, package the processor as a jar instead of shipping an exploded dir"],"exampleFix":"# before: unreadable declaration file -> directory assumed processor-free\nls libs/processor-classes/META-INF/services/javax.annotation.processing.Processor\n# file exists but is locked/corrupt\n\n# after: rebuild restores a readable declaration\n./gradlew :processor:clean :processor:compileJava","handlingStrategy":"validation","validationCode":"// guard: every processor classes dir must expose a readable, non-empty declaration\ndef dir = file('libs/processor-classes')\ndef decl = new File(dir, 'META-INF/services/javax.annotation.processing.Processor')\nassert decl.isFile() && decl.canRead() : \"unreadable processor declaration in ${dir}\"\nassert decl.readLines().any { it.trim() && !it.startsWith('#') } : \"empty processor declaration in ${dir}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not mutate classes directories while a build is scanning them; publish jars instead","Exclude build output directories from antivirus real-time scanning on Windows","Run ./gradlew clean after interrupted builds to discard half-written outputs"],"tags":["gradle","annotation-processing","incremental-compilation","file-io","java"],"backgroundTag":"annotation-processor-metadata-unreadable","analyzedSha":"534f27719b66953f95cc907aae7f2c1b12f5482d","analyzedAt":"2026-08-22T08:09:12.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}