flowable/flowable-engine · critical · FlowableException

couldn't open resource stream: " + e.getMessage()

Error message

couldn't open resource stream: " + e.getMessage()

What it means

DmnEngines.buildDmnEngine wraps the resource's URL.openStream() call; when opening the stream throws IOException (resource missing, unreadable, or connection failure), the engine rethrows it as a FlowableException. This happens during engine initialization from a configuration resource URL, so it usually means the DMN engine configuration file could not be read.

Source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/DmnEngines.java:164

            dmnEngineInfo = new EngineInfo(dmnEngineName, resourceUrlString, null);
            dmnEngines.put(dmnEngineName, dmnEngine);
            dmnEngineInfosByName.put(dmnEngineName, dmnEngineInfo);
        } catch (Throwable e) {
            LOGGER.error("Exception while initializing dmn engine: {}", e.getMessage(), e);
            dmnEngineInfo = new EngineInfo(null, resourceUrlString, ExceptionUtils.getStackTrace(e));
        }
        dmnEngineInfosByResourceUrl.put(resourceUrlString, dmnEngineInfo);
        dmnEngineInfos.add(dmnEngineInfo);
        return dmnEngineInfo;
    }

    protected static DmnEngine buildDmnEngine(URL resource) {
        try (InputStream inputStream = resource.openStream()) {
            DmnEngineConfiguration dmnEngineConfiguration = DmnEngineConfiguration.createDmnEngineConfigurationFromInputStream(inputStream);
            return dmnEngineConfiguration.buildDmnEngine();

        } catch (IOException e) {
            throw new FlowableException("couldn't open resource stream: " + e.getMessage(), e);
        }
    }

    /** Get initialization results. */
    public static List<EngineInfo> getDmnEngineInfos() {
        return dmnEngineInfos;
    }

    /**
     * Get initialization results. Only info will we available for dmn engines which were added in the {@link DmnEngines#init()}. No {@link EngineInfo} is available for engines which were registered
     * programmatically.
     */
    public static EngineInfo getDmnEngineInfo(String dmnEngineName) {
        return dmnEngineInfosByName.get(dmnEngineName);
    }

    public static DmnEngine getDefaultDmnEngine() {
        return getDmnEngine(NAME_DEFAULT);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the resource URL points to an existing, readable configuration file (check the path with new File(url.toURI()).exists() or curl for http URLs).
  2. If the resource is on the classpath, build the URL with getClass().getClassLoader().getResource("flowable.dmn.cfg.xml") instead of hand-constructing a file path.
  3. Check file permissions and that the process user can read the file.
  4. Inspect the wrapped IOException (e.getCause()) for the underlying reason (FileNotFoundException, ConnectException, etc.).

Example fix

// before
URL url = new URL("file:config/flowable.dmn.cfg.xml"); // file missing
DmnEngine engine = DmnEngines.buildDmnEngine(url);

// after
URL url = DmnEngines.class.getClassLoader().getResource("flowable.dmn.cfg.xml");
if (url == null) throw new IllegalStateException("flowable.dmn.cfg.xml not on classpath");
DmnEngine engine = DmnEngines.buildDmnEngine(url);
Defensive patterns

Strategy: try-catch

Validate before calling

URL url = DmnEngines.class.getClassLoader().getResource("flowable.dmn.cfg.xml");
if (url == null) throw new IllegalStateException("DMN engine config resource not found on classpath");

Type guard

if (resource == null || resource.toString().isBlank()) { throw new IllegalArgumentException("resource URL required"); }

Try / catch

try {
    DmnEngine engine = DmnEngines.buildDmnEngine(url);
} catch (FlowableException e) {
    Throwable cause = e.getCause(); // IOException with real reason
    LOGGER.error("Cannot open DMN config resource {}: {}", url, cause.getMessage(), cause);
    throw new IllegalStateException("DMN engine init failed: bad resource", e);
}

Prevention

When it happens

Trigger: Calling DmnEngines.initDmnEngineFromResource / buildDmnEngine with a URL whose openStream() throws IOException — e.g. a file:// URL pointing to a nonexistent or unreadable flowable.cfg.xml, or an unreachable http:// resource.

Common situations: Wrong classpath resource path typo in flowable.cfg.xml lookup; file deleted or moved after URL was resolved; insufficient file permissions; remote config URL down or DNS failure.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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