{"record":{"id":"10570e24ac489b23","repo":"SonarSource/sonarqube","slug":"jre-files-in-jresdir-do-not-match-jres-metadata","errorCode":null,"errorMessage":"JRE files in ${jresDir} do not match jres-metadata.json (missing: ${missing}, unexpected: ${extra}). Run './gradlew clean' to remove stale JREs, then rebuild.","messagePattern":"JRE files in (.+?) do not match jres-metadata\\.json \\(missing: (.+?), unexpected: (.+?)\\)\\. Run '\\./gradlew clean' to remove stale JREs, then rebuild\\.","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"sonar-application/build.gradle","lineNumber":490,"sourceCode":"  mustRunAfter cyclonedxBom\n  doLast {\n    // Check for stale JREs: the jres directory should contain exactly as many files as jres-metadata.json.\n    // Extra files from a previous JRE version inflate the zip and can cause the size check below to fail.\n    // Fix: run './gradlew clean' to remove stale JREs, then rebuild.\n    // Match files by name against metadata instead of raw count to tolerate unrelated entries (.DS_Store, partial downloads, etc.)\n    def jresDir = layout.buildDirectory.dir('jres').get().asFile\n    def jresMetadata = new JsonSlurper().parse(file(layout.projectDirectory.dir('src/main/resources/jres-metadata.json').asFile))\n    def expectedNames = jresMetadata.collect { it.filename } as Set\n    def actualNames = (jresDir.listFiles()?.collect { it.name } ?: []) as Set\n    def missing = expectedNames - actualNames\n    def extra = actualNames - expectedNames\n    if (missing || extra) {\n      def message =\n        \"JRE files in ${jresDir} do not match jres-metadata.json (missing: ${missing}, unexpected: ${extra}). \" +\n          \"Run './gradlew clean' to remove stale JREs, then rebuild.\"\n      // Strict in CI; warn locally so leftover .DS_Store / partial downloads don't abort local builds.\n      if (System.getenv(\"CI\") == \"true\") {\n        throw new GradleException(message)\n      }\n      logger.warn(message)\n    }\n\n    // When the archive size increases due to dependencies, the expected size should be updated as well.\n    // Unknown failures may cause the archive size to shrink accidentally in size.\n    //\n    // This check is in place as a protection so that the developer checks why the size increased or decreased\n    // out of this expected area.\n    //\n    // If the change is expected, modify the expectedSize to be whatever the archiveSize is rounded down to the nearest 10MB.\n    // The calculation below will also tell you the number you should use here.\n    // If this is not expected, try performing a Gradle clean and refreshing dependencies.\n    // Non-release builds skip re-compressing already-compressed entries (see skipAlreadyCompressed above), which\n    // trades a larger archive for a much faster build; release builds fully compress, staying close to the old size.\n    def expectedSize = release ? 940_000_000 : 990_000_000\n    // We set a tolerance to avoid failing the build for small differences in the archive size.\n    def tolerance = 15_000_000","sourceCodeStart":472,"sourceCodeEnd":508,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/sonar-application/build.gradle#L472-L508","documentation":"The distribution build validates that downloaded JRE files under the jres directory exactly match jres-metadata.json. If files are missing or unexpected extras exist, in CI (env CI=true) it throws this GradleException; locally it only logs a warning so leftover .DS_Store files or partial downloads don't abort builds.","triggerScenarios":"A previous interrupted build left partial JRE downloads; OS noise files (e.g. .DS_Store) in jresDir; metadata updated without cleaning, leaving stale JRE files not listed in jres-metadata.json; running the zip task in CI with a dirty workspace.","commonSituations":"Retrying a failed download that half-completed; switching branches where jres-metadata.json changed; macOS developer artifacts checked into the directory.","solutions":["Run './gradlew clean' then rebuild to remove stale/partial JREs","Manually delete the jres directory contents and re-run the build so files re-download per metadata","If a legitimately new file is flagged, update jres-metadata.json to include it"],"exampleFix":"// before\n./gradlew assemble\n// after\n./gradlew clean assemble","handlingStrategy":"validation","validationCode":"// shell: ensure jres dir matches metadata before CI build\n# after a failed build or branch switch:\n./gradlew clean","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run ./gradlew clean after branch switches or failed JRE downloads","Exclude OS noise (.DS_Store) from the jres directory","Re-download all JREs whenever jres-metadata.json changes","Use a clean CI workspace per build"],"tags":["gradle","build","checksum","ci"],"backgroundTag":"checksum-mismatch","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}