NullPointerException от Catalina при запуске Tomcat с ресурсами JMS Tibco EMS JNDI

в моем приложении Primefaces я хочу использовать JMSBroadcaster фреймворка атмосферы для распространения сообщений между двумя экземплярами моего приложения.

Для этого мне нужно найти (JNDI) JMS ConnectionFactory и Topic (используемая нами реализация — Tibco EMS).

Я новичок в JMS и не могу понять, как настроить ресурс Tibco JMS в Tomcat context.xml и server.xml (я не использую активный MQ). Я пытаюсь объявить эти ресурсы JMS из EMS в Tomcat 8. Я добавил tibjms-7.0.1.jar и jboss-jms-api_1.1_spec-1.0.1.Final.jar в tomcat8/lib/

Но при запуске tomcat я получаю следующую ошибку (даже без развернутой войны):

СЕРЬЕЗНЫЙ [основной] org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans RuntimeException java.lang.NullPointerException

Я не могу понять, в чем проблема (я не уверен, что могу получить более подробную информацию об этой зарегистрированной ошибке).

Вот моя конфигурация tomcat:

In 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"/>

In 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" />

В качестве альтернативы меня также может заинтересовать способ настройки JMSBroadcaster атмосферы с использованием ConnectionFactory и Topic, введенных из Spring.


person Marc Bouvier    schedule 07.06.2016    source источник


Ответы (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 для публикации моего сообщения в теме вместо 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);
person Marc Bouvier    schedule 18.10.2016