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.