History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: AMQ-1217
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Aman Nanner
Votes: 3
Watchers: 5
Operations

If you were logged in you would be able to see more operations.
ActiveMQ

Message Bridge to Weblogic 9.2 results in Null JMS Destination

Created: 30/Mar/07 08:39 AM   Updated: 12/Jul/08 11:50 AM
Component/s: Broker
Affects Version/s: 4.1.0
Fix Version/s: 5.2.0

Time Tracking:
Not Specified

File Attachments:
  Size
File Licensed for inclusion in ASF works patchAMQ-1217-NPE-CompositeDestinationBroker.diff 2007-10-10 02:32 AM Lilians AUVIGNE 0.9 kb
Java Source File Licensed for inclusion in ASF works WLSToActiveMQMessageConverter.java 2008-07-12 11:50 AM Guy Veraghtert 0.9 kb


 Description  « Hide
Hi,

I have created an inbound message bridge from Weblogic Server 9.2 into Apache Geronimo 1.2 (Apache Active MQ 4.1-SNAPSHOT). The actual "bridge" works fine, as the message is forwarded from Weblogic Server into Apache ActiveMQ. However, a NullPointerException occurs during processing of the message:

Bar.java
11:15:40,885 ERROR [DestinationBridge] failed to forward message on attempt: 1 reason: javax.jms.JMSException: java.lang.NullPointerException message: TextMessage[ID:Sphinx-3592-1175266963549-3:1:3:1:5, <test>Hello World</test>]
javax.jms.JMSException: java.lang.NullPointerException
	at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:46)
	at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1181)
	at org.apache.activemq.ActiveMQSession.send(ActiveMQSession.java:1551)
	at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:465)
	at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:415)
	at org.apache.activemq.ActiveMQQueueSender.send(ActiveMQQueueSender.java:116)
	at org.apache.activemq.network.jms.QueueBridge.sendMessage(QueueBridge.java:87)
	at org.apache.activemq.network.jms.DestinationBridge.onMessage(DestinationBridge.java:134)
	at weblogic.jms.client.JMSSession.onMessage(JMSSession.java:4060)
	at weblogic.jms.client.JMSSession.execute(JMSSession.java:3953)
	at weblogic.jms.client.JMSSession$UseForRunnable.run(JMSSession.java:4467)
	at weblogic.work.ExecuteRequestAdapter.execute(ExecuteRequestAdapter.java:21)
	at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145)
	at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117)
Caused by: java.lang.NullPointerException
	at org.apache.activemq.broker.CompositeDestinationBroker.send(CompositeDestinationBroker.java:86)
	at org.apache.activemq.broker.MutableBrokerFilter.send(MutableBrokerFilter.java:136)
	at org.apache.activemq.broker.TransportConnection.processMessage(TransportConnection.java:498)
	at org.apache.activemq.command.ActiveMQMessage.visit(ActiveMQMessage.java:604)
	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:294)
	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:185)
	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:95)
	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:65)
	at org.apache.activemq.transport.vm.VMTransport.syncOneWay(VMTransport.java:96)
	at org.apache.activemq.transport.vm.VMTransport.oneway(VMTransport.java:83)
	at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:47)
	at org.apache.activemq.transport.ResponseCorrelator.asyncRequest(ResponseCorrelator.java:69)
	at org.apache.activemq.transport.ResponseCorrelator.request(ResponseCorrelator.java:74)
	at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1175)
	... 12 more

Here is the method in org.apache.activemq.broker.CompositeDestinationBroker where the NullPointerException occurs:


Bar.java
public void send(ConnectionContext context, Message message) throws Exception {
        ActiveMQDestination destination = message.getDestination();
        if( destination.isComposite() ) {
            ActiveMQDestination[] destinations = destination.getCompositeDestinations();
            for (int i = 0; i < destinations.length; i++) {
                if( i!=0 ) {
                    message = message.copy();
                }
                message.setOriginalDestination(destination);
                message.setDestination(destinations[i]);
                message.evictMarshlledForm();
                next.send(context, message);
            }
        } else {
            next.send(context, message);
        }
    }

The message.getDestination() method call returns null because the JMS Destination inside the message is set to null. I then investigated why this message would be set to null, and I traced the problem to the following method in org.apache.activemq.ActiveMQSession:


Bar.java
protected void send(ActiveMQMessageProducer producer, ActiveMQDestination destination, Message message, int deliveryMode,
            int priority, long timeToLive) throws JMSException {
        checkClosed();

        if( destination.isTemporary() && connection.isDeleted(destination) ) {
            throw new JMSException("Cannot publish to a deleted Destination: "+destination);
        }

        // tell the Broker we are about to start a new transaction
        doStartTransaction();
        TransactionId txid = transactionContext.getTransactionId();
        
        message.setJMSDestination(destination);
        message.setJMSDeliveryMode(deliveryMode);        
        long expiration = 0L;

        if (!producer.getDisableMessageTimestamp()) {
            long timeStamp = System.currentTimeMillis();
            message.setJMSTimestamp(timeStamp);
            if (timeToLive > 0) {
                expiration = timeToLive + timeStamp;
            }
        }

        message.setJMSExpiration(expiration);
        message.setJMSPriority(priority);
        long sequenceNumber = producer.getMessageSequence();
        
        message.setJMSRedelivered(false);        

        // transform to our own message format here
        ActiveMQMessage msg = ActiveMQMessageTransformation.transformMessage(message, connection);
        // Set the message id.
        if( msg == message ) {
            msg.setMessageId( new MessageId(producer.getProducerInfo().getProducerId(), sequenceNumber) );
        } else {
            msg.setMessageId( new MessageId(producer.getProducerInfo().getProducerId(), sequenceNumber) );
            message.setJMSMessageID(msg.getMessageId().toString());
        }
        
        msg.setTransactionId(txid);

        if ( connection.isCopyMessageOnSend() ){
            msg = (ActiveMQMessage) msg.copy();
        }
        msg.setConnection(connection);
        msg.onSend();
        msg.setProducerId(msg.getMessageId().getProducerId());

        if (log.isDebugEnabled()) {
            log.debug("Sending message: " + msg);
        }

        if( !connection.isUseSyncSend() && ( !msg.isPersistent() || connection.isUseAsyncSend() || txid!=null) ) {
            this.connection.asyncSendPacket(msg);
        } else {
            this.connection.syncSendPacket(msg);
        }

    }

As you can see, the destination is supposed to be set in the message during the call message.setJMSDestination(destination);. I have verified that the destination argument is indeed valid and NOT null. However, after this method invocation, the internal JMS destination within the "message" object is STILL null.

This "message" object is in fact the Weblogic JMS implementation of the "Message" interface. So it seems that the Weblogic implementation of the object is not properly setting the JMS destination for whatever reason. Therefore, when the message is transformed in the following call:

ActiveMQMessage msg = ActiveMQMessageTransformation.transformMessage(message, connection);

the new ActiveMQMessage object will have a null destination, thus causing a NullPointerException further down the chain.

It may be that the fact that the JMS destination is not being set in the Weblogic JMS class is a Weblogic bug, but I'm wondering if Apache ActiveMQ should anticipate this somehow, and still be able to deliver the JMS message.

Thanks



 All   Comments   Work Log   Change History   Subversion Commits   FishEye   Crucible      Sort Order: Ascending order - Click to sort in descending order
a2wes - 07/May/07 10:01 AM
Has there been any suggestion for a fix for this bug, or is anyone aware of a workaround?

Tony Longworth - 08/May/07 09:39 AM
I'm also very interested in a fix or workaround.

We have exactly the same problem between Weblogic Server 8.1 and ActiveMQ 4.1.1 (and 4.1.0).


Lilians AUVIGNE - 10/Oct/07 02:32 AM
Just a simple patch for not log NullPointerException, because the bridge works fine.

Guy Veraghtert - 12/Jul/08 11:50 AM
If you are configuring the bridge via the activemq.xml config file, there is a workaround. Register the attached JmsMessageConverter on the jmsConnector:

<jmsBridgeConnectors>
<jmsQueueConnector name="WLSToActiveMQBridge-Inbound"
jndiOutboundTemplate="#remoteJndi"
outboundQueueConnectionFactoryName="weblogic.examples.jms.QueueConnectionFactory"
inboundMessageConvertor="#converter"
localQueueConnectionFactory="#localFactory">
<inboundQueueBridges>
<inboundQueueBridge inboundQueueName="be.aca.sourceWLSQueue" localQueueName="be.aca.targetActiveMQQueue"/>
</inboundQueueBridges>
</jmsQueueConnector>
</jmsBridgeConnectors>

<bean id="remoteJndi" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">t3://localhost:7001</prop>
</props>
</property>
</bean>

<bean id="localFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>

<bean id="converter" class="be.aca.WLSToActiveMQMessageConverter"/>