在我的Primefaces应用程序中,我想使用大气框架的JMSBroadcaster
,以便在我的应用程序的两个实例之间传播消息。
为此,我需要为JMS ConnectionFactory
和Topic
查找(JNDI)(我们使用的实现是Tibco EMS)。
我是JMS的新手,我无法想象如何在Tomcat的context.xml
和server.xml
中配置Tibco JMS资源(我没有使用活动MQ)。我试图在Tomcat 8中从EMS声明这些JMS资源。
我在tibjms-7.0.1.jar
jboss-jms-api_1.1_spec-1.0.1.Final.jar
和tomcat8/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注入的JMSBroadcaster
和ConnectionFactory
来配置氛围的Topic
。
答案 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);