{"record":{"id":"7a5d19b23702d3bc","repo":"flowable/flowable-engine","slug":"failed-to-read-resource-resource-7a5d19","errorCode":null,"errorMessage":"Failed to read resource ${resource}","messagePattern":"Failed to read resource (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-app-engine/src/main/java/org/flowable/app/engine/impl/repository/AppDeploymentBuilderImpl.java","lineNumber":82,"sourceCode":"\n        AppResourceEntity resource = resourceEntityManager.create();\n        resource.setName(resourceName);\n        resource.setBytes(bytes);\n        deployment.addResource(resource);\n        return this;\n    }\n\n    @Override\n    public AppDeploymentBuilder addClasspathResource(String resource) {\n        try (final InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(resource)) {\n            if (inputStream == null) {\n                throw new FlowableException(\"resource '\" + resource + \"' not found\");\n            }\n            \n            return addInputStream(resource, inputStream);\n            \n        } catch (IOException ex) {\n            throw new FlowableException(\"Failed to read resource \" + resource, ex);\n        }\n    }\n\n    @Override\n    public AppDeploymentBuilder addString(String resourceName, String text) {\n        if (text == null) {\n            throw new FlowableException(\"text is null\");\n        }\n\n        AppResourceEntity resource = resourceEntityManager.create();\n        resource.setName(resourceName);\n        resource.setBytes(text.getBytes(StandardCharsets.UTF_8));\n        deployment.addResource(resource);\n        return this;\n    }\n    \n    @Override\n    public AppDeploymentBuilder addBytes(String resourceName, byte[] bytes) {","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-app-engine/src/main/java/org/flowable/app/engine/impl/repository/AppDeploymentBuilderImpl.java#L64-L100","documentation":"If reading the classpath resource stream raises an IOException while opening or closing it, addClasspathResource() wraps the IOException in FlowableException(\"Failed to read resource ...\"). Note that the 'not found' FlowableException from the try block is not an IOException and propagates unchanged; this message specifically means an I/O problem, and its cause holds the details.","triggerScenarios":"The try-with-resources block in addClasspathResource fails with IOException — typically when closing a stream backed by a jar/zip entry that is corrupted, or when a custom classloader throws while reading the resource.","commonSituations":"Corrupted jars in the classpath; resources inside nested jars handled by custom classloaders; JVM-level I/O problems (disk errors, security managers blocking reads); fat-jar packaging issues where entries cannot be reopened.","solutions":["Inspect the cause chain of the FlowableException to find the underlying IOException source.","Rebuild/re-download the artifact — a corrupted jar is the most common root cause.","Extract the resource to the filesystem at startup and deploy from a FileInputStream instead of reading it through the classloader.","Check for a security manager or custom classloader interfering with resource reads."],"exampleFix":"// before\ndeploymentBuilder.addClasspathResource(\"apps/myApp.bar\"); // IOException from corrupted jar\n\n// after\nbyte[] data = Files.readAllBytes(Paths.get(\"conf/apps/myApp.bar\")); // read from filesystem\ndeploymentBuilder.addInputStream(\"myApp.bar\", new ByteArrayInputStream(data));","handlingStrategy":"try-catch","validationCode":"try (InputStream test = getClass().getClassLoader().getResourceAsStream(resource)) { if (test == null || test.read() == -1) { throw new IllegalStateException(\"Resource unreadable or empty: \" + resource); } }","typeGuard":null,"tryCatchPattern":"try { deploymentBuilder.addClasspathResource(resource); } catch (FlowableException e) { log.error(\"Reading resource {} failed: {}\", resource, e.getCause(), e); }","preventionTips":["Inspect e.getCause() for the underlying IOException; corrupted jars are the usual culprit.","Verify jar integrity (checksums) in CI to catch corrupted dependencies early.","For problematic packaged resources, extract them to disk at startup and deploy via FileInputStream."],"tags":["flowable","deployment","io-error","classpath"],"backgroundTag":"file-read-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}