【问题标题】:NullPointerException from Catalina when starting Tomcat with JMS Tibco EMS JNDI resources使用 JMS Tibco EMS JNDI 资源启动 Tomcat 时来自 Catalina 的 NullPointerException
【发布时间】:2016-10-18 22:11:15
【问题描述】:

在我的 Primefaces 应用程序中,我想使用大气框架的 JMSBroadcaster 在我的应用程序的 2 个实例之间传播消息。

为此,我需要查找 (JNDI) JMS ConnectionFactoryTopic(我们使用的实现是 Tibco EMS)。

我对 JMS 很陌生,我不知道如何在 Tomcat 的 context.xmlserver.xml 中配置 Tibco JMS 资源(我没有使用活动 MQ)。我正在尝试从 Tomcat 8 中的 EMS 声明这些 JMS 资源。 我在tomcat8/lib/ 中添加了tibjms-7.0.1.jarjboss-jms-api_1.1_spec-1.0.1.Final.jar

但是,在 tomcat 启动时,我收到以下错误(即使没有部署任何战争):

严重 [main] org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans RuntimeException java.lang.NullPointerException

我无法弄清楚问题出在哪里(我不确定我能否获得有关此记录错误的更多详细信息)。

这是我的 tomcat 配置:

server.xml

<Resource 
    id="atmosphereFactory" 
    name="jms/atmosphereFactory"   
    jndiName="atmosphereFactory"  
    auth="Container"  
    type="com.tibco.tibjms.naming.TibjmsInitialContextFactory"  
    factory="com.tibco.tibjms.naming.TibjmsObjectFactory"  
    factoryClass="com.tibco.tibjms.naming.TibjmsInitialContextFactory"  
    brokerName="localhost"  
    brokerURL="tcp://localhost:7222"  
    serverUrl="localhost:7222"  
    userName="admin"  
    password="" />
<Resource 
    id="atmosphere" 
    name="jms/atmosphere/test.atmo"
    jndiName="atmosphere"
    auth="Container"
    type="com.tibco.tibjms.TibjmsTopic" 
    factory="com.tibco.tibjms.naming.TibjmsObjectFactory"
    physicalName="test.atmo"/>

context.xml

<ResourceLink 
    global="jms/atmosphereFactory" 
    name="jms/atmosphereFactory" 
    type="com.tibco.tibjms.naming.TibjmsInitialContextFactory" />
<ResourceLink 
    global="jms/atmosphere" 
    name="jms/atmosphere" 
    type="com.tibco.tibjms.TibjmsTopic" />

另外,我也可能对使用从 Spring 注入的 ConnectionFactoryTopic 配置大气的 JMSBroadcaster 的方法感兴趣。

【问题讨论】:

    标签: tomcat jms jndi atmosphere tibco-ems


    【解决方案1】:

    其实我是用Spring来实例化Jms Topic...

    <!-- Connection to Tibco EMS -->
    <bean id="tibjmsConnectionFactory" class="com.tibco.tibjms.TibjmsConnectionFactory">
        <property name="serverUrl" value="${instance.jms.server}" />
        <property name="userName" value="${instance.jms.login}"/>
        <property name="userPassword" value="${instance.jms.password}"/>
    </bean>
    
    <bean id="jmsTemplateEms" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="tibjmsConnectionFactory" />
        <property name="explicitQosEnabled" value="true" />
        <property name="deliveryMode" value="2" />
        <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE" />
        <property name="sessionTransacted" value="false" />
        <property name="receiveTimeout" value="${instance.wait.timeout}" />
    </bean>
    
    <bean id="pushJmsMessageListener" class="com.agipi.g2a.tiana.web.utils.PushJmsMessageListener" />
    
    <bean id="atmosphereTopic" class="com.tibco.tibjms.TibjmsTopic">
        <!-- nom du topic-->
        <constructor-arg index="0" value="${instance.jms.atmosphere.topic.name}" />
    </bean>
    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="tibjmsConnectionFactory"/>
        <property name="destination" ref="atmosphereTopic"/>
        <property name="messageListener" ref="pushJmsMessageListener" />
    </bean>
    

    ... 并创建了一个 MessageListener 来监听气氛主题并将收到的消息发布到 Push 事件总线 ...

    class PushJmsMessageListener implements MessageListener {
        private static final Logger LOGGER = LoggerFactory.getLogger(PushJmsMessageListener.class);
    
        private static final String PROPERTY_PUSH_CHANNEL = "pushChannel";
    
        @Override
        public void onMessage(Message message) {
    
            try {
                EventBus eventBus = EventBusFactory.getDefault().eventBus();
                TextMessage testMessage = (TextMessage) message;
                LOGGER.info("Reception d'un message du topic atmosphere : {}", testMessage);
    
                String canal = testMessage.getStringProperty(PROPERTY_PUSH_CHANNEL);
                Object decodedObject = new JSONDecoder().decode(testMessage.getText());
                LOGGER.info("Envoi du message sur le endpoint push [canal={},objet={}]", canal, decodedObject);
                eventBus.publish(canal, decodedObject);
            } catch (JMSException e) {
                LOGGER.error("error.receiving.jms.message", e);
    
            }
        }
    }
    

    ...并创建了一个 Spring 服务来将我的消息发布到主题而不是推送...

    @Service
    @Scope(value = "singleton")
    public class JmsAtmosphereServiceImpl implements JmsAtmosphereService {
    
        @Autowired
        @Qualifier("jmsTemplateEms")
        private JmsTemplate jmsTemplate;
    
        @Autowired
        @Qualifier("atmosphereTopic")
        private Topic atmosphereTopic;
    
    
        @Override
        public void sendMessage(String pushChannel, String jsonContent) {
            jmsTemplate.send(atmosphereTopic, session -> {
                TextMessage textMessage = session.createTextMessage(jsonContent);
                textMessage.setStringProperty("pushChannel", pushChannel);
                return textMessage;
            });
    
        }
    
    }
    

    ...一些用于抽象的实用程序...

    @Service
    public class PushJmsUtils {
    
        private static final String PUSH_DEFAULT_CHANNEL = "atmosphere";
    
        @Autowired
        private JmsAtmosphereService jmsAtmosphereService;
    
        /**
         * Propagate message JMS as JSON to JMS Atmosphere topic.
         *
         * @param channel push channel
         * @param message object to send via push
         */
        public void propagateMessage(String channel, Object message) {
            String id = channel;
            if (id.startsWith("/*")) {
                id = PUSH_DEFAULT_CHANNEL;
            }
            jmsAtmosphereService.sendMessage(id, new JSONEncoder().encode(message));
        }
    
    }
    

    .. 然后,我将我的消息发布到我的应用程序的多个实例,这些实例监听相同的气氛主题(包括发送消息的应用程序)。

     pushJmsUtils.propagateMessage(canal,pushMessage);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      相关资源
      最近更新 更多