ActiveMQ: исключение NullPointerException на брокере при проверке авторизации - PullRequest
1 голос
/ 01 марта 2012

Я использую ActiveMQ 5.3.0 в среде OSGi два года без каких-либо заметных проблем.

Теперь мне нужно добавить управление авторизацией для пользователей, которые публикуют / подписываются на определенные темы. Для этой цели я разработал плагин, который реализует 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 со стековой трассировкой:

 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)

Теперь, если я удалю фрагмент, чтобы прочитать содержимое сообщения XML в isAllowedToConsume (...), все элементы будут возвращаться нормально, но мне нужен такой элемент управления !!!

Итак, есть ли способ правильно прочитать TextMessage, не затрагивая других потребителей?

Большое спасибо и простите за длинный вопрос !!

Bye cghersi

Редакция 1 (@nico_ekito):

Здесь есть полный метод 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...       
}
...