Nullpointer while creating a remote JMS Session
belcar Sep 30, 2009 5:47 AMHi all
My JMS client application running on JBoss 4.2.3 fails to create a remote JMS Session on startup due to a NullpointerException. The JMS server is JBM 1.4.4 on JBoss AS 4.2.3. Threads mentioned below already discuss the issue, but even when trying to change the scoping/loader the issue remains.
13:37:18,980 INFO [StartupListener] ~~ Creating JMS Session ... 13:37:18,989 FATAL [StartupListener] java.lang.NullPointerException at org.jboss.jms.client.container.FailoverValveInterceptor.invoke(FailoverValveInterceptor.j ava:87) at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:105) at org.jboss.jms.client.delegate.ClientConnectionDelegate$createSessionDelegate_605233526772 4906805.invokeNext(ClientConnectionDelegate$createSessionDelegate_6052335267724906805.java) at org.jboss.jms.client.container.ClosedInterceptor.invoke(ClosedInterceptor.java:170) at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:105) at org.jboss.jms.client.delegate.ClientConnectionDelegate$createSessionDelegate_605233526772 4906805.invokeNext(ClientConnectionDelegate$createSessionDelegate_6052335267724906805.java) at org.jboss.jms.client.delegate.ClientConnectionDelegate.createSessionDelegate(ClientConnec tionDelegate.java) at org.jboss.jms.client.JBossConnection.createSessionInternal(JBossConnection.java:269) at org.jboss.jms.client.JBossConnection.createSession(JBossConnection.java:91)
This standalone WAR file connects to the JBM server from the ServletContextListener.contextInitialized() callback method to poll for messages. The code was tested on windows platform(on 1 machine) but now fails during linux deployments where both servers are remote.
http://www.jboss.org/index.html?module=bb&op=viewtopic&t=110051&postdays=0&postorder=asc&start=0
https://jira.jboss.org/jira/browse/JBMESSAGING-980
http://www.jboss.org/community/wiki/ClassLoadingconfiguration
On the client server I removed the server/default/deploy/jms folder to remove JBossMQ. In the WEB-INF/lib of my WAR I've provided jboss-remoting.jar (v2.2.3) and jboss-messaging-client.jar (v1.4.4).
Here is my Spring configuration:
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
<prop key="java.naming.provider.url">jnp://someIP:1099</prop>
<prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>
</props>
</property>
</bean>
<bean id="threadPoolSize" class="java.lang.Integer">
<constructor-arg value="${threadPoolSize}"/>
</bean>
<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate"><ref bean="jndiTemplate" /></property>
<property name="jndiName" value="/ConnectionFactory"/>
</bean>
<bean id="requestQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate"><ref bean="jndiTemplate" /></property>
<property name="jndiName" value="${queue}"/>
</bean>and here is the code that initializes the connection:
public class StartupListener implements ServletContextListener {
private static final Log log = LogFactory.getLog(StartupListener.class);
private static Connection connection;
private static Session session;
private static MessageConsumer consumer;
private static Boolean run = Boolean.TRUE;
private static ExecutorService pool;
private static Thread daemonThread;
private static final String PREFIX = " ~~ ";
private static MeteoService metService;
/**
* Startup trigger of the application.
*/
public void contextInitialized(ServletContextEvent ctx) {
log.info("==== Initializing ServiceBroker");
logInfo("Creating polling thread ...");
daemonThread = new Thread(new MessageDispatcher());
try {
ApplicationContext _ctx = WebApplicationContextUtils.getWebApplicationContext(ctx.getServletConte
xt());
initializeWorkerThreadPool(_ctx);
initializeJMSEnvironment(_ctx);
metService = (MeteoService) _ctx.getBean("metService");
logInfo("Starting the Session ...");
connection.start();
logInfo("Starting a Daemon Thread responsible for message dispatching ...");
daemonThread.start();
log.info("==== ServiceBroker initialized successfully");
} catch (Throwable e) {
log.fatal(e.getMessage(), e);
}
}
/**
* This is a context lifecycle (callback) method.
* The Servlet Context is being destroyed by the Container due to a shutdown.
* As a result we need to clean up our privately managed resources.
*/
public void contextDestroyed(ServletContextEvent ctx) {
synchronized (run) {
log.info("==== Shutting down PilotBriefing ServiceBroker ...");
run = Boolean.FALSE;
logInfo("Interrupting polling thread ...");
daemonThread.interrupt();
if (session != null) {
try {
logInfo("Closing JMS Session ...");
session.close();
} catch (JMSException e) {
log.error(e.getMessage(), e);
}
}
if (connection != null) {
try {
logInfo("Closing JMS Connection ...");
connection.close();
} catch (JMSException e) {
log.error(e.getMessage(), e);
}
}
if (pool != null) {
logInfo("Shutting down ThreadPool");
pool.shutdownNow();
}
log.info("==== ServiceBroker shutdown complete");
}
}
private void logInfo(String msg) {
log.info(PREFIX + msg);
}
/**
* Initialization of JMS environment.
* @param _ctx external configuration parameters
* @throws NamingException
* @throws JMSException
*/
private void initializeJMSEnvironment(ApplicationContext _ctx) throws NamingException, JMSException
{
Queue queue = (Queue) _ctx.getBean("requestQueue");
logInfo("Lookup of ConnectionFactory ...");
ConnectionFactory cf = (ConnectionFactory) _ctx.getBean("jmsConnectionFactory");
logInfo("Creating JMS Connection ...");
connection = cf.createConnection();
logInfo("Creating JMS Session ...");
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
logInfo("Creating MessagConsumer ...");
consumer = session.createConsumer(queue);
}
/**
* Setup a pool of worker threads for message handling.
* @param _ctx external configuration parameters
*/
private void initializeWorkerThreadPool(ApplicationContext _ctx) {
int poolSize = (Integer) _ctx.getBean("threadPoolSize");
logInfo("Initializing Thread Pool [#" + poolSize + "] ...");
pool = Executors.newFixedThreadPool(poolSize);
}
/**
* Daemon thread for the dispatching of incoming messages to a pooled Worker Thread that will handl
e the request.
* This class is implemented as a Thread because otherwise the Servlet Container Thread that execut
es this listener class,
* fails to complete as a result of the polling-loop.
*/
class MessageDispatcher implements Runnable {
public void run() {
try {
while (run) {
TextMessage message = (TextMessage) consumer.receive();
if (message != null) {
JMSUtils.printMessage("Received request", message);
pool.execute(createMessageHandler(message));
}
}
} catch (Throwable t) {
log.error(t.getMessage(), t);
}
}
/**
* Factory method.
* @param message
* @return
* @throws JMSException
*/
private Runnable createMessageHandler(TextMessage message) throws JMSException {
return new MessageHandler(metService, session, message.getJMSReplyTo(), message.getJMSMessageID()
, message.getText());
}
}I've searched and tried every possible thing but I cannot get past this issue. Any help is much appreciated.