Historically I've deployed my JMS consumer applications as Spring webapps deployed under Tomcat (Windows box). These consumers will then run alongside my other webapps under the same Tomcat instance. As the number of consumers that I use has grown, however, I've realized that this is turning into a bit of a maintenance nightmare.
My solution was to convert these webapps to "main method" standalone apps deployed as jars. In fact, I was able to successfully package them all together in an attempt to reuse as many resources (DAO, dependencies, etc) as possible.
Here's what my main method looks like:
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
try {
FooListener fooListener = (FooListener) context.getBean("fooListener");
fooListener.start();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
try {
BarListener barListener = (BarListener) context.getBean("barListener");
barListener.start();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
My question(s):
Edit:
A bit more information: FooListener and BarListener extend the following abstract class. They inherit their values from the corresponding beans in the applicationContext.xml file, and they both override the onMessage() method to asynchronously consume messages.
public abstract class TextMessageListener implements MessageListener {
protected ConnectionFactory connectionFactory;
protected String queueName;
protected String selectors;
public void start() throws JMSException {
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(session.createQueue(queueName), selectors);
consumer.setMessageListener(this);
connection.start();
}
public abstract void onMessage(Message message);
}
You have to register a shutdown hook for your application context this way:
context.registerShutdownHook();
This will ensure that when the jvm is shutdown, the context is also closed gracefully.
My personal preference is always to deploy it to a container - even standalone apps like these, this is because of the following reasons:
Also, why are you explicitly calling the listener.start(), the Spring container does this automatically anyway?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With