我在OSGi环境下使用ActiveMQ 5.3.0两年没有任何明显的问题。
现在,我需要为发布/订阅特定主题的用户添加授权管理。 为此,我开发了一个插件,在方法
中实现了org.apache.activemq.security.MessageAuthorizationPolicy:public boolean isAllowedToConsume(ConnectionContext context, Message message)
我在那里读取传入的消息,我检查当前用户是否允许使用这样的消息,并且我相应地返回true / false进行此检查。 特别是,我使用短信(简短的XML片段......),所以,我使用这个片段来读取当前的TextMessage:
if (message instanceof TextMessage) {
String xmlText = "";
try {
xmlText = xml.getText();
System.out.println(xmlText);
... //parse the message and check for permission...
} catch (JMSException e) {
... //manage exception
}
}
在我看来(但也许我错了!!)此代码使用org.apache.activemq.openwire.v5.MessageMarshaller中包含的代码创建了一场竞赛:
public void tightMarshal2(OpenWireFormat wireFormat, Object o, DataOutput dataOut, BooleanStream bs) throws IOException {
...
tightMarshalByteSequence2(info.getContent(), dataOut, bs); //here, info.getContent() is null!!
...
}
实际上我收到了一个NullPointerException,其stacktrace是:
Exception in thread "BrokerService"
java.lang.NullPointerException
at org.apache.activemq.openwire.v5.BaseDataStreamMarshaller.tightMarshalByteSequence2(BaseDataStreamMarshaller.java:431)
at org.apache.activemq.openwire.v5.MessageMarshaller.tightMarshal2(MessageMarshaller.java:180)
at org.apache.activemq.openwire.v5.ActiveMQMessageMarshaller.tightMarshal2(ActiveMQMessageMarshaller.java:89)
at org.apache.activemq.openwire.v5.ActiveMQTextMessageMarshaller.tightMarshal2(ActiveMQTextMessageMarshaller.java:89)
at org.apache.activemq.openwire.OpenWireFormat.tightMarshalNestedObject2(OpenWireFormat.java:430)
at org.apache.activemq.openwire.v5.BaseDataStreamMarshaller.tightMarshalNestedObject2(BaseDataStreamMarshaller.java:136)
at org.apache.activemq.openwire.v5.MessageDispatchMarshaller.tightMarshal2(MessageDispatchMarshaller.java:105)
at org.apache.activemq.openwire.OpenWireFormat.marshal(OpenWireFormat.java:240)
at org.apache.activemq.transport.tcp.TcpTransport.oneway(TcpTransport.java:166)
at org.apache.activemq.transport.InactivityMonitor.oneway(InactivityMonitor.java:237)
at org.apache.activemq.transport.TransportFilter.oneway(TransportFilter.java:83)
at org.apache.activemq.transport.WireFormatNegotiator.oneway(WireFormatNegotiator.java:104)
at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:40)
at org.apache.activemq.broker.TransportConnection.dispatch(TransportConnection.java:1190)
at org.apache.activemq.broker.TransportConnection.processDispatch(TransportConnection.java:779)
at org.apache.activemq.broker.TransportConnection.iterate(TransportConnection.java:815)
at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
现在,如果我删除片段以在isAllowedToConsume(...)中读取消息的XML内容,那么所有的seeems都会正常返回,但我需要这样的控件!!!
那么,有没有办法正确读取TextMessage而不影响其他消费者呢?
非常感谢,对不起这个长期的问题感到抱歉!!
再见 cghersi
这里有完整的isAllowedToConsume()方法:
public boolean isAllowedToConsume(ConnectionContext context, Message message) {
String msgFrom = message.getDestination().getPhysicalName();
String textOfMsg = "";
if(message instanceof TextMessage){
TextMessage xml = (TextMessage)message;
try {
textOfMsg = xml.getText();
} catch (JMSException e) {
return false;
}
} else
return false;
//do my checks on textOfMsg returning true/false...
}