flowable/flowable-engine · error · IllegalStateException

DMN engine has not been initialized

Error message

DMN engine has not been initialized

What it means

During Spring Boot auto-configuration, Flowable exposes the already-initialized DMN engine as a bean by fetching it from the DmnEngines static registry. If the DMN engine has not been initialized by the time this @Bean method runs, the registry has no default engine and this IllegalStateException is thrown. It is a startup-order guard: the injected ProcessEngine is expected to have bootstrapped the DMN engine.

Solutions

  1. Ensure a ProcessEngine (flowable-spring-boot-starter-process) is on the classpath and auto-configured so it initializes the DMN engine before this bean method runs
  2. Let Flowable build the DMN engine itself: use the standard DmnEngineConfiguration bean instead of relying on the 'already-initialized' path
  3. Check for @ConditionalOnMissingBean overrides or exclusions (e.g. spring.autoconfigure.exclude) that suppress engine initialization
  4. Initialize the DMN engine explicitly in a BeanFactoryPostProcessor/early bean so DmnEngines.isInitialized() is true

Example fix

// before: custom bean created before engine init
@Bean DmnEngine dmnEngine() { return DmnEngines.getDefaultDmnEngine(); }
// after: depend on process engine so init order is guaranteed
@Bean DmnEngine dmnEngine(ProcessEngine processEngine) {
    if (!DmnEngines.isInitialized()) throw new IllegalStateException("...");
    return DmnEngines.getDefaultDmnEngine();
}
Defensive patterns

Strategy: validation

Validate before calling

if (!DmnEngines.isInitialized()) { throw new IllegalStateException("Start the ProcessEngine before requesting the DmnEngine bean"); }

Type guard

boolean dmnAvailable = DmnEngines.isInitialized();

Try / catch

try { return DmnEngines.getDefaultDmnEngine(); } catch (IllegalStateException e) { /* fall back to building a DmnEngine locally */ }

Prevention

When it happens

Trigger: Spring Boot auto-configuration selects AlreadyInitializedEngineConfiguration and the dmnEngine(ProcessEngine) bean method runs while DmnEngines.isInitialized() is false — i.e. the ProcessEngine (or standalone DMN engine) was never built before this bean was requested.

Common situations: Mixing flowable-spring-boot starters with manual engine configuration; disabling the ProcessEngine auto-configuration while keeping DMN bean exposure; custom bean definitions that build engines lazily or in the wrong order; excluding the engine initializer beans.

Related errors


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

Appendix: source

Thrown at modules/flowable-spring-boot/flowable-spring-boot-starters/flowable-spring-boot-autoconfigure/src/main/java/org/flowable/spring/boot/dmn/DmnEngineServicesAutoConfiguration.java:71

    /**
     * If a process engine is present that means that the DmnEngine was created as part of it.
     * Therefore extract it from the DmnEngines.
     */
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingBean(type = {
        "org.flowable.dmn.engine.DmnEngine",
        "org.flowable.app.engine.AppEngine"
    })
    @ConditionalOnBean(type = {
        "org.flowable.engine.ProcessEngine"
    })
    static class AlreadyInitializedEngineConfiguration {
        @Bean
        public DmnEngine dmnEngine(@SuppressWarnings("unused") ProcessEngine processEngine) {
            // The process engine needs to be injected, as otherwise it won't be initialized, which means that the DmnEngine is not initialized yet
            if (!DmnEngines.isInitialized()) {
                throw new IllegalStateException("DMN engine has not been initialized");
            }
            return DmnEngines.getDefaultDmnEngine();
        }
    }
    
    /**
     * If an app engine is present that means that the DmnEngine was created as part of the app engine.
     * Therefore extract it from the DmnEngines.
     */
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingBean(type = {
        "org.flowable.dmn.engine.DmnEngine"
    })
    @ConditionalOnBean(type = {
        "org.flowable.app.engine.AppEngine"
    })
    static class AlreadyInitializedAppEngineConfiguration {

View on GitHub (pinned to d6d39ce1c6)