{"record":{"id":"6b5856f428ef2208","repo":"flowable/flowable-engine","slug":"could-not-load-image-for-case-diagram-creation","errorCode":null,"errorMessage":"Could not load image for case diagram creation: {}","messagePattern":"Could not load image for case diagram creation: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"modules/flowable-cmmn-image-generator/src/main/java/org/flowable/cmmn/image/impl/DefaultCaseDiagramCanvas.java","lineNumber":211,"sourceCode":"        g.setFont(font);\n        this.fontMetrics = g.getFontMetrics();\n\n        LABEL_FONT = new Font(labelFontName, Font.ITALIC, 10);\n        ANNOTATION_FONT = new Font(annotationFontName, Font.PLAIN, FONT_SIZE);\n\n        try {\n            TIMER_IMAGE = ImageIO.read(ReflectUtil.getResource(\"org/flowable/icons/timer.png\", customClassLoader));\n            USERLISTENER_IMAGE = ImageIO.read(ReflectUtil.getResource(\"org/flowable/icons/user.png\", customClassLoader));\n            VARIABLELISTENER_IMAGE = ImageIO.read(ReflectUtil.getResource(\"org/flowable/icons/variablelistener.png\", customClassLoader));\n            USERTASK_IMAGE = ImageIO.read(ReflectUtil.getResource(\"org/flowable/icons/userTask.png\", customClassLoader));\n            SERVICETASK_IMAGE = ImageIO.read(ReflectUtil.getResource(\"org/flowable/icons/serviceTask.png\", customClassLoader));\n            CASETASK_IMAGE = ImageIO.read(ReflectUtil.getResource(\"org/flowable/icons/caseTask.png\", customClassLoader));\n            PROCESSTASK_IMAGE = ImageIO.read(ReflectUtil.getResource(\"org/flowable/icons/processTask.png\", customClassLoader));\n            DECISIONTASK_IMAGE = ImageIO.read(ReflectUtil.getResource(\"org/flowable/icons/decisionTask.png\", customClassLoader));\n            SENDEVENTTASK_IMAGE = ImageIO.read(ReflectUtil.getResource(\"org/flowable/icons/sendEventTask.png\", customClassLoader));\n\n        } catch (IOException e) {\n            LOGGER.warn(\"Could not load image for case diagram creation: {}\", e.getMessage());\n        }\n    }\n\n    /**\n     * Generates an image of what currently is drawn on the canvas.\n     *\n     * Throws an {@link FlowableImageException} when {@link #close()} is already called.\n     */\n    public InputStream generateImage(String imageType) {\n        if (closed) {\n            throw new FlowableImageException(\"CaseDiagramGenerator already closed\");\n        }\n\n        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {\n            ImageIO.write(caseDiagram, imageType, out);\n            return new ByteArrayInputStream(out.toByteArray());\n        } catch (IOException e) {\n            throw new FlowableImageException(\"Error while generating case image\", e);","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-image-generator/src/main/java/org/flowable/cmmn/image/impl/DefaultCaseDiagramCanvas.java#L193-L229","documentation":"During static initialization of DefaultCaseDiagramCanvas, the icon PNGs (caseTask.png, processTask.png, decisionTask.png, sendEventTask.png) are loaded from the classpath via ImageIO.read. If any of them cannot be read or found, an IOException is caught and only a warning is logged, leaving the static image fields null. Diagram generation will then produce task nodes without icons or fail later when drawing them.","triggerScenarios":"Creating a DefaultCaseDiagramCanvas (or generating a CMMN case diagram) when org/flowable/icons/*.png resources are not resolvable through the provided customClassLoader, or the classpath resource is corrupt/unreadable so ImageIO.read throws IOException.","commonSituations":"Shaded/minified jars or custom classloaders (e.g. OSGi, Spring Boot fat jar with filtering) that exclude or corrupt icon resources; build resource filtering mangling PNG binaries; running with an incomplete flowable-image-generator dependency or repackaged flowable jars missing icon resources.","solutions":["Verify the flowable-cmmn-image-generator jar contains org/flowable/icons/*.png and that your classloader can load them (unzip -l the jar).","Disable Maven/Gradle resource filtering on binary files (png) or add nonFilteredFileExtensions for png.","If using a custom ClassLoader, pass one that can see the flowable jar resources, or null to use the default.","Check the underlying e.getMessage() in the log: 'Can't read input file' vs 'not found' tells you whether the resource is missing or corrupt.","Ensure icons are read before any ImageIO Usages are affected: pin a standard flowable release instead of a custom repack."],"exampleFix":"// before (pom.xml resource filtering mangles PNGs)\n<resource><directory>src/main/resources</directory><filtering>true</filtering></resource>\n// after\n<resource><directory>src/main/resources</directory><filtering>false</filtering></resource>","handlingStrategy":"fallback","validationCode":"try (var in = getClass().getClassLoader().getResourceAsStream(\"org/flowable/icons/caseTask.png\")) {\n    if (in == null) throw new IllegalStateException(\"flowable icon resources missing from classpath\");\n}","typeGuard":"boolean iconsAvailable(ClassLoader cl) {\n    return cl.getResource(\"org/flowable/icons/caseTask.png\") != null\n        && cl.getResource(\"org/flowable/icons/processTask.png\") != null\n        && cl.getResource(\"org/flowable/icons/decisionTask.png\") != null\n        && cl.getResource(\"org/flowable/icons/sendEventTask.png\") != null;\n}","tryCatchPattern":"try {\n    new DefaultCaseDiagramGenerator().generateDiagram(model, imageType, activityFont);\n} catch (RuntimeException e) {\n    LOGGER.warn(\"Diagram generation unavailable (icons not loadable), skipping diagram\", e);\n    return null; // fallback: proceed without diagram\n}","preventionTips":["Keep png files out of resource filtering in Maven/Gradle builds.","Verify shaded/fat jars retain org/flowable/icons/* resources (check archive contents in CI).","Smoke-test diagram generation on the packaged artifact, not just in IDE.","If using custom classloaders (OSGi, app servers), ensure the flowable image generator bundle can see its own resources."],"tags":["image-io","classpath","diagram-generation","resource-missing"],"backgroundTag":"file-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}