Skip to content

Make jmsListenerContainerFactory @ConditionalOnSingleCandidate #12700

Closed
@danlangford

Description

@danlangford

I am wondering if it would be appropriate to add @ConditionalOnSingleCandidate to jmsListenerContainerFactory? I have an application that sends messages to multiple brokers and as such i create multiple ConnectionFactory and JMSTemplate beans. My application does not need to listen to any JMS destinations. my application fails to start because it is finding multiple ConnectionFactory beans and as such unable to create the default jmsListenerContainerFactory bean. For clarity, my application does not need a listener.

if i understand this correctly we are getting into this position because due to the MATCHED conditions listed below.

AutoConfigure on class JmsAutoConfiguration:

@Configuration
@ConditionalOnClass({ Message.class, JmsTemplate.class })
@ConditionalOnBean(ConnectionFactory.class)
@EnableConfigurationProperties(JmsProperties.class)
@Import(JmsAnnotationDrivenConfiguration.class)
public class JmsAutoConfiguration {

@ConditionalOnClass({ Message.class, JmsTemplate.class }) MATCHES those ARE on the classpath
@ConditionalOnBean(ConnectionFactory.class) MATCHES i have multiple CopnnectionFactories
@Import(JmsAnnotationDrivenConfiguration.class)

Configure JmsAnnotationDrivenConfiguration:

@Configuration
@ConditionalOnClass(EnableJms.class)
class JmsAnnotationDrivenConfiguration {

@ConditionalOnClass(EnableJms.class) MATCHES that class is on the classpath

@Bean
@ConditionalOnMissingBean(name = "jmsListenerContainerFactory")
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(
DefaultJmsListenerContainerFactoryConfigurer configurer,
ConnectionFactory connectionFactory) {

@ConditionalOnMissingBean(name = "jmsListenerContainerFactory") MATCHES i did not define my own

and then that method is requiring just one ConnectionFactory parameter but I have made multiple.

would adding @ConditionalOnSingleCandidate be a quality of life improvement here? Would it make it so that a listenerContainerFactory is not created and my application can start without error? or am i misunderstanding the use/purpose of that annotation?

workarounds i played with trying to get my application to start

  • i set spring.jms.listener.auto-startup=false however the problem persisted
  • i can make a ConnectionFactory Bean @Primary but.... i dont want or need a listener so it feels like that is making the error go away by conforming to its current design. its allowing its current design to dictate how my application is configured which is incorrect and misleading to other developers. none of my connections are necessarily Primary
  • currently i have created my own jmsListenerContainerFactory bean so that spring-boot does not try to autoconfigure its own. this is messier than the @Primary work around from a code quality point of view but at least i know i am killing the creation of a listenerContainerFactory as early as i can see to kill it.

or have I missed something and I am way off base? is there some other property to communicate to spring "please do not register any listeners"?

Thanks

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions