{"record":{"id":"d6b93bffcc9ae408","repo":"alibaba/spring-ai-alibaba","slug":"failed-to-delete-jar-file","errorCode":null,"errorMessage":"Failed to delete JAR file: ","messagePattern":"Failed to delete JAR file: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/utils/FileUtils.java","lineNumber":121,"sourceCode":"\t\t\tthrow new RuntimeException(\"Failed to copy JAR files to working directory\", e);\n\t\t}\n\t}\n\n\t/**\n\t * Deletes all JAR files from the specified working directory.\n\t * @param workDir The working directory from which the JAR files will be deleted.\n\t */\n\tpublic static void deleteResourceJarFromWorkDir(String workDir) {\n\t\ttry {\n\t\t\tPath workDirPath = Path.of(workDir);\n\t\t\tif (Files.exists(workDirPath)) {\n\t\t\t\ttry (var stream = Files.walk(workDirPath)) {\n\t\t\t\t\tstream.filter(path -> path.toString().endsWith(\".jar\")).forEach(jarPath -> {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tFiles.deleteIfExists(jarPath);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (IOException e) {\n\t\t\t\t\t\t\tthrow new RuntimeException(\"Failed to delete JAR file: \" + jarPath, e);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\tthrow new RuntimeException(\"Failed to delete JAR files from working directory\", e);\n\t\t}\n\t}\n\n}\n","sourceCodeStart":103,"sourceCodeEnd":133,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/utils/FileUtils.java#L103-L133","documentation":"FileUtils.deleteResourceJarFromWorkDir walks the working directory and deletes every .jar file via Files.deleteIfExists. An IOException on any individual delete is wrapped in this RuntimeException naming the JAR path.","triggerScenarios":"Files.deleteIfExists fails for a specific jar: file locked by a running process (e.g. a JVM/URLClassLoader still holding the jar open on Windows), permission denied on the file or parent directory, or the path became a directory mid-walk.","commonSituations":"On Windows, JARs loaded into a classloader remain locked; work directory owned by another user; antivirus briefly locking files; delete attempted while the code-execution process is still running.","solutions":["Close any URLClassLoader or streams holding the JAR open before deleting.","Verify file/parent directory write permissions for the deleting user.","Retry the delete after the consuming process (e.g. the executed java/shell job) has exited.","Check e.getCause() to distinguish permission denied from file-in-use."],"exampleFix":"// before\nFiles.deleteIfExists(jarPath); // may fail while jar is locked\n// after\nif (!classLoaderClosed) {\n    classLoader.close(); // release jar handles first\n}\nboolean deleted = Files.deleteIfExists(jarPath);\nif (!deleted) { logger.debug(\"jar already absent: {}\", jarPath); }","handlingStrategy":"retry","validationCode":"Path dir = Path.of(workDir);\nif (!Files.isDirectory(dir) || !Files.isWritable(dir)) {\n    throw new IllegalStateException(\"workDir missing or not writable: \" + workDir);\n}","typeGuard":null,"tryCatchPattern":"try {\n    FileUtils.deleteResourceJarFromWorkDir(workDir);\n} catch (RuntimeException e) {\n    logger.warn(\"JAR delete failed ({}), will retry after process exit\", e.getMessage());\n    // retry later, e.g. scheduled cleanup\n}","preventionTips":["Close classloaders/streams referencing the JARs before deleting (critical on Windows).","Delete JARs only after the executed code process has terminated.","Schedule cleanup retries for transient locks (antivirus, file watchers).","Run the cleanup with a user that owns the work directory."],"tags":["file-delete","io","jar"],"backgroundTag":"file-delete-failed","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}