flowable/flowable-engine · warning

Could not load image for decision requirements diagram…

Error message

Could not load image for decision requirements diagram creation: {}

What it means

A WARN from DefaultDecisionRequirementsDiagramCanvas.initialize: the built-in icon resource org/flowable/icons/decision.png could not be read via ImageIO (IOException). The DECISION_IMAGE field stays null, which can later cause NullPointerExceptions or degraded rendering when the DRD image is generated.

Solutions

  1. Verify the flowable-dmn-image-generator jar contains org/flowable/icons/decision.png (jar tf ...) and re-download/refresh the dependency if missing.
  2. Avoid shading/excluding Flowable resource files in maven-shade/minimizeJar configuration.
  3. Check the custom classloader passed to the canvas can see Flowable classpath resources.
  4. Install AWT/ImageIO dependencies if the IOException stems from missing image codec support.

Example fix

// before (shade config)
<minimizeJar>true</minimizeJar>
// after
<minimizeJar>false</minimizeJar>
<!-- or add filter keeping org/flowable/icons/** -->
Defensive patterns

Strategy: fallback

Validate before calling

boolean iconPresent = getClass().getClassLoader().getResource("org/flowable/icons/decision.png") != null;

Try / catch

try { new DefaultDecisionRequirementsDiagramGenerator().generateDiagram(...); } catch (Throwable t) { log.warn("Skipping diagram generation: {}", t.getMessage()); }

Prevention

When it happens

Trigger: Constructing DefaultDecisionRequirementsDiagramCanvas (during DRD generation on DMN deployment) when the flowable-dmn-image-generator jar is corrupted/incomplete or the custom classloader cannot resolve the icon resource.

Common situations: Uber/fat-jar packaging or shading that drops resources; classloader restrictions in application servers/OSGi; partially downloaded dependency in a local Maven repository; running under a classloader that hides org.flowable resources.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/be46ce5af380a1d7. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-dmn-image-generator/src/main/java/org/flowable/dmn/image/impl/DefaultDecisionRequirementsDiagramCanvas.java:183

        if (!"png".equalsIgnoreCase(imageType)) {
            this.g.setBackground(new Color(255, 255, 255, 0));
            this.g.clearRect(0, 0, canvasWidth, canvasHeight);
        }

        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setPaint(Color.black);

        Font font = new Font(activityFontName, Font.BOLD, FONT_SIZE);
        g.setFont(font);
        this.fontMetrics = g.getFontMetrics();

        LABEL_FONT = new Font(labelFontName, Font.ITALIC, 10);
        ANNOTATION_FONT = new Font(annotationFontName, Font.PLAIN, FONT_SIZE);

        try {
         DECISION_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/decision.png", customClassLoader));
        } catch (IOException e) {
            LOGGER.warn("Could not load image for decision requirements diagram creation: {}", e.getMessage());
        }
    }

    /**
     * Generates an image of what currently is drawn on the canvas.
     *
     * Throws an {@link FlowableImageException} when {@link #close()} is already called.
     */
    public InputStream generateImage(String imageType) {
        if (closed) {
            throw new FlowableImageException("CaseDiagramGenerator already closed");
        }

        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            ImageIO.write(decisionRequirementsDiagram, imageType, out);
            return new ByteArrayInputStream(out.toByteArray());
        } catch (IOException e) {
            throw new FlowableImageException("Error while generating case image", e);

View on GitHub (pinned to d6d39ce1c6)