andrewdleach
andrewdleach

Reputation: 2466

Why does DefaultJmsListenerContainerFactory not expose setExceptionListener method?

I am in the process of building out telemetry and monitoring for an application that uses a DefaultJmsListenerContainerFactory to register @JmsListener annotated methods.

I already have an error handler registered for exceptions thrown while receiving a message, but I want to register a similar error handler to monitor the connection integrity between my app and the topic(s) to which it is subscribed.

I found this nifty setExceptionListener method in AbstractMessageListenerContainter, but the DefaultJmsListenerContainerFactory does not provide a configuration method to set this attribute.

I've searched through the spring framework JMS javadocs to see if there's any explanation as to why this configuration option doesn't exist. Does anyone know of a reason why this is not exposed?

Upvotes: 1

Views: 918

Answers (2)

andrewdleach
andrewdleach

Reputation: 2466

Here is what eventually provided me access to this attribute. I tested that I can still receive messages from the topic as before

public class PortalJmsListenerContainerFactory
        extends DefaultJmsListenerContainerFactory {

    private ExceptionListener exceptionListener;

    /**
     * @see DefaultMessageListenerContainer#setExceptionListener
     */
    public void setExceptionListener(ExceptionListener exceptionListener) {
        this.exceptionListener = exceptionListener;
    }

    @Override
    protected DefaultMessageListenerContainer createContainerInstance() {
        return new DefaultMessageListenerContainer();
    }

    @Override
    protected void initializeContainer(DefaultMessageListenerContainer container) {
        super.initializeContainer(container);

        if (this.exceptionListener != null) {
            container.setExceptionListener(this.exceptionListener);
        }
    }

}

Upvotes: 2

Gary Russell
Gary Russell

Reputation: 174729

Looks like an omission, or was considered not something that was felt necessary to expose. I suggest you open an Improvement JIRA issue.

In the meantime you can get a reference to the container from the JmsListenerEndpointRegistry (using the id), cast it and set the property.

EDIT

Something like this should work...

@Bean
public SmartInitializingSingleton lcPostProcessor(JmsListenerEndpointRegistry registry) {
    return () -> registry.getListenerContainers().forEach(c ->
            ((DefaultMessageListenerContainer) c).setExceptionListener(myExceptionListener()));
}

It runs after all the beans are created but before any containers are started.

Upvotes: 2

Related Questions