flowable/flowable-engine · error · IllegalStateException

Could not resolve the JmsListenerContainerFactory to use for

Error message

Could not resolve the JmsListenerContainerFactory to use for [<endpoint>] no factory was given and no default is set.

What it means

resolveContainerFactory (mirroring Spring's JmsListenerAnnotationBeanPostProcessor logic) determines which JmsListenerContainerFactory builds the endpoint's listener container. If no factory was set directly, no containerFactoryBeanName was configured, and no default factory exists, it throws an IllegalStateException naming the endpoint.

Solutions

  1. Define a default JmsListenerContainerFactory bean named 'jmsListenerContainerFactory' in your Spring context.
  2. Set the channel model's container factory bean name to an existing JmsListenerContainerFactory bean.
  3. Ensure the JmsChannelModelProcessor's beanFactory is set if resolving the factory by bean name.
  4. Verify the factory bean type is JmsListenerContainerFactory (not, e.g., a Kafka factory).

Example fix

// before: no factory bean

// after
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory cf) {
    DefaultJmsListenerContainerFactory f = new DefaultJmsListenerContainerFactory();
    f.setConnectionFactory(cf);
    return f;
}
Defensive patterns

Strategy: validation

Validate before calling

if (beanFactory != null && !beanFactory.containsBean("jmsListenerContainerFactory")) {
    throw new IllegalStateException("Define a jmsListenerContainerFactory bean before registering JMS endpoints");
}

Try / catch

try {
    processor.registerEndpoint(channelModel, tenantId);
} catch (IllegalStateException e) {
    log.error("No JmsListenerContainerFactory for endpoint {}", channelModel.getKey(), e);
}

Prevention

When it happens

Trigger: registerEndpoint for a JMS channel where neither a container factory instance, a container factory bean name, nor a default JmsListenerContainerFactory bean is available in the BeanFactory.

Common situations: No 'jmsListenerContainerFactory' bean defined in the Spring context; channel model's container-factory reference misconfigured; BeanFactory not injected into the processor.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/jms/JmsChannelModelProcessor.java:232

        // This also makes sure that we are not going to start our listener earlier than the JmsListenerEndpointRegistry
        boolean startImmediately = contextRefreshed || endpointRegistry.isRunning();
        logger.info("Registering endpoint {} with start immediately {}", endpoint, startImmediately);
        endpointRegistry.registerListenerContainer(endpoint, resolveContainerFactory(endpoint, factory), startImmediately);
        logger.info("Finished registering endpoint {}", endpoint);
    }

    protected JmsListenerContainerFactory<?> resolveContainerFactory(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> containerFactory) {
        if (containerFactory != null) {
            return containerFactory;
        } else if (this.containerFactory != null) {
            return this.containerFactory;
        } else if (containerFactoryBeanName != null) {
            Assert.state(beanFactory != null, "BeanFactory must be set to obtain container factory by bean name");
            // Consider changing this if live change of the factory is required...
            this.containerFactory = beanFactory.getBean(containerFactoryBeanName, JmsListenerContainerFactory.class);
            return this.containerFactory;
        } else {
            throw new IllegalStateException("Could not resolve the " +
                JmsListenerContainerFactory.class.getSimpleName() + " to use for [" +
                endpoint + "] no factory was given and no default is set.");
        }
    }

    protected String getEndpointId(ChannelModel channelModel, String tenantId) {
        String channelDefinitionKey = channelModel.getKey();
        if (!StringUtils.hasText(tenantId)) {
            return CHANNEL_ID_PREFIX + channelDefinitionKey;
        }
        return CHANNEL_ID_PREFIX + tenantId + "#" + channelDefinitionKey;
    }

    protected String resolve(String value) {
        if (embeddedValueResolver != null) {
            return embeddedValueResolver.resolveStringValue(value);
        } else {
            return value;

View on GitHub (pinned to d6d39ce1c6)