使用JMS Tibco EMS JNDI资源启动Tomcat时Catalina的NullPointerException

时间:2016-06-07 12:32:51

标签: tomcat jms jndi atmosphere tibco-ems

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

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

我是JMS的新手,我无法想象如何在Tomcat的context.xmlserver.xml中配置Tibco JMS资源(我没有使用活动MQ)。我试图在Tomcat 8中从EMS声明这些JMS资源。 我在tibjms-7.0.1.jar

中添加了jboss-jms-api_1.1_spec-1.0.1.Final.jartomcat8/lib/

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

  

SEVERE [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注入的JMSBroadcasterConnectionFactory来配置氛围的Topic

1 个答案:

答案 0 :(得分:0)

我实际上使用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服务来将我的消息发布到主题而不是push ...

@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);