Bug 656488 - Java client null pointer exception thrown when there is no exchange set for ReplyTo
Summary: Java client null pointer exception thrown when there is no exchange set for R...
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Red Hat Enterprise MRG
Classification: Red Hat
Component: qpid-java
Version: 1.3
Hardware: Unspecified
OS: Unspecified
high
high
Target Milestone: 1.3.2-RC2
: ---
Assignee: Rajith Attapattu
QA Contact: Frantisek Reznicek
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-11-23 20:56 UTC by Mike Cressman
Modified: 2018-11-14 16:34 UTC (History)
5 users (show)

Fixed In Version: qpid-java-0.7.946106-15
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed:
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
Current issue reproducers (no success to reproduce so far) (7.20 KB, application/x-tbz)
2011-01-14 13:58 UTC, Frantisek Reznicek
no flags Details
ReplyToTest which reproduces the issue (2.34 KB, text/x-java)
2011-01-19 08:35 UTC, Frantisek Reznicek
no flags Details
Reproducer for both issues (1.90 KB, application/octet-stream)
2011-01-29 00:57 UTC, Rajith Attapattu
no flags Details

Description Mike Cressman 2010-11-23 20:56:11 UTC
Description of problem:

If the ReplyTo exchange is not set on a message read by the Java client, and getJMSReplyTo is called, the code does not properly handle the exchange being null.

In the following code, replyTo.getExchange() returns null, so the String exchange is set to null, and thus the first argument to generateDestination ends up being null.

AMQMessageDelegate_0_10.getJMSReplyTo() line: 224	
            if (dest == null)
            {
                String exchange = replyTo.getExchange();
                String routingKey = replyTo.getRoutingKey();

                dest = generateDestination(exchange == null ? null : new AMQShortString(exchange),
                        routingKey == null ? null : new AMQShortString(routingKey));

In the following code, you can see that if the first argument (exchange) is null, you'll get a null pointer exception when the code attempts to call exchange.asString().

protected AMQDestination generateDestination(AMQShortString exchange, AMQShortString routingKey)
    {
        AMQDestination dest;
        ExchangeInfo exchangeInfo = _exchangeMap.get(exchange.asString());


Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1. send a message with no reply info from a python client and read it from the java client
2. call getJMSReplyTo() in the java client
3. 
  
Actual results:

Caused by: java.lang.NullPointerException
at org.apache.qpid.client.message.AbstractAMQMessageDelegate.generateDestination(AbstractAMQMessageDelegate.java:96)
at org.apache.qpid.client.message.AMQMessageDelegate_0_10.getJMSReplyTo(AMQMessageDelegate_0_10.java:224)
at org.apache.qpid.client.message.AbstractJMSMessage.getJMSReplyTo(AbstractJMSMessage.java:133)

Expected results:
Handle the null properly without throwing an exception

Additional info:
This happens when the generating client is python, but not C# or java.

Comment 1 Rajith Attapattu 2010-11-24 20:37:20 UTC
I have committed a fix upstream at rev 1038773
This is tracked in upstream via QPID-2959

http://svn.apache.org/viewvc/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java?rev=1038773&r1=1038772&r2=1038773&view=diff

Comment 2 Rajith Attapattu 2011-01-12 14:19:41 UTC
The fix was ported to the internal release repo.

http://mrg1.lab.bos.redhat.com/cgit/qpid.git/commit/?h=mrg_1.3.0.x&id=143f7adce7827a1b37c5fabffea637cd06a1c02e

Comment 3 Rajith Attapattu 2011-01-13 23:33:09 UTC
The fixes have been incorporated into qpid-java-0.7.946106-14 for RHEL 4/5/6.

Comment 4 Frantisek Reznicek 2011-01-14 13:58:26 UTC
Created attachment 473524 [details]
Current issue reproducers (no success to reproduce so far)

I'm unable to reproduce the issue neither RHEL4.8, nor 5.6 i386 / x86_64 on qpid-java-0.7.946106-10/12 with other latest packages or with packages from last November.


The way I reproduce it is:
1] ./Spout2 --count=3 "ADDRq; {create:always, delete:receiver}"
2] ./run_example.sh org.apache.qpid.example.Drain2 "ADDRq; {create:always, delete:receiver}"

where Spout2 and Drain2 are modified python resp. Java high level API examples which are attached.

There seems to be a missing information in the definition.


The result I get now is:
  [root@dhcp-27-225 bz656488]# ./Spout2 "ADDR1; {create:always, delete:receiver}"
  Message()
  [root@dhcp-27-225 bz656488]# ./run_example.sh org.apache.qpid.example.Drain2 "ADDR1; {create:always, delete:receiver}"
  {}
  Jan 14, 2011 1:23:46 PM org.apache.qpid.client.AMQConnection <init>
  INFO: Connection:amqp://guest:********@test/test?brokerlist='tcp://localhost:5672'
  Jan 14, 2011 1:23:46 PM org.apache.qpid.client.protocol.AMQProtocolSession <init>
  INFO: Using ProtocolVersion for Session:0-10
  Jan 14, 2011 1:23:46 PM org.apache.qpid.client.handler.ClientMethodDispatcherImpl newMethodDispatcher
  INFO: New Method Dispatcher:AMQProtocolSession[null]
  Jan 14, 2011 1:23:46 PM org.apache.qpid.client.AMQConnection <init>
  INFO: Connecting with ProtocolHandler Version:0-10
  Jan 14, 2011 1:23:47 PM org.apache.qpid.client.AMQConnection <init>
  INFO: Connected with ProtocolHandler Version:0-10
  Jan 14, 2011 1:23:47 PM org.apache.qpid.client.AMQSession <init>
  INFO: Created session:org.apache.qpid.client.AMQSession_0_10@4aeaf40c
  Jan 14, 2011 1:23:47 PM org.apache.qpid.client.AMQSession registerConsumer
  INFO: Prefetching delayed existing messages will not flow until requested via receive*() or setML().
  Jan 14, 2011 1:23:47 PM org.apache.qpid.client.AMQSession startDispatcherIfNecessary
  INFO: Dispatcher-Channel-1 created
  Jan 14, 2011 1:23:47 PM org.apache.qpid.client.AMQSession$Dispatcher run
  INFO: Dispatcher-Channel-1 started
  
  ------------- Msg -------------
  Body:
  ""
  JMS Correlation ID: null
  JMS timestamp: 0
  JMS expiration: 0
  JMS priority: 4
  JMS delivery mode: 2
  JMS reply to: null
  JMS Redelivered: false
  JMS Destination: :///ADDR1/ADDR1?routingkey='ADDR1'
  JMS Type: null
  JMS MessageID: null
  JMS Content-Type: application/octet-stream
  AMQ message number: 2
  Properties:<NONE>
  -------------------------------
  
  Jan 14, 2011 1:23:47 PM org.apache.qpid.client.AMQSession close
  INFO: Closing session: org.apache.qpid.client.AMQSession_0_10@4aeaf40c
  Jan 14, 2011 1:23:47 PM org.apache.qpid.client.BasicMessageConsumer close
  INFO: Closing consumer:1[190139698]
  Jan 14, 2011 1:23:47 PM org.apache.qpid.client.AMQSession$Dispatcher run
  INFO: Dispatcher-Channel-1 thread terminating for channel 1:org.apache.qpid.client.AMQSession_0_10@4aeaf40c

Comment 5 Frantisek Reznicek 2011-01-14 13:59:25 UTC
Raising NEEDINFO.

Comment 6 Frantisek Reznicek 2011-01-14 14:14:12 UTC
Details about Spout2 and Drain2.


Spout2 is python spout which sends messages with content and subject only, i.e.

    msg = Message(subject=opts.subject,
                  content=content)

another case with was tried with same result:

    msg = Message(subject=opts.subject,
                  reply_to=None,
                  content=content)


Drain2 receives message and queries the reply to twice following way:

  Message msg;
  ...
  Destination rt;
  msg = consumer.receive(timeout)
  rt = msg.getJMSReplyTo();
  System.out.println(msg);
  rt = msg.getJMSReplyTo();


which should be exactly as described above.

Please let me know whether above code snippets / attached examples are ok.

Reproducibility is not specified, assuming 100%, is that correct?

There is possibility that above described issue is present on specific combinations of python and java clients (versions).
qpid-java-0.7.946106-10 / 12 vs. python-qpid-0.7.946106-14 was used.

Comment 7 Frantisek Reznicek 2011-01-19 08:35:49 UTC
Created attachment 474219 [details]
ReplyToTest which reproduces the issue

The issue has been retested from different angles on last and previous packages (-14 / -12 / -7) with following results:
- I'm not able to reproduce scenario python client -> java client
  using queue / topic address
- I got from Mike the original reproducer which is fully in Java (sender + receiver)
  This small program is reproducing the issue rapidly on either set of packages, i.e. also on latest ones where issue should be solved.

Below pasted null pointer exception is the same as the reported one (with small line change in AbstractAMQMessageDelegate.java ).


-> ASSIGNED


Additional info:

  [root@mrg-qe-07 bz656488]# QPID_DEPS=`find /usr/share/java/qpid-deps/*.jar | tr '\n' ":"`
  [root@mrg-qe-07 bz656488]# QPID_JARS=`find /usr/share/java -name 'qpid-client*.jar' -or -name 'qpid-common*.jar' | tr '\n' ":"`
  [root@mrg-qe-07 bz656488]# LOG4J="/usr/share/java/log4j.jar"
  [root@mrg-qe-07 bz656488]# javac -cp  "$QPID_DEPS$LOG4J:$QPID_JARS" ReplyToTest.java
  [root@mrg-qe-07 bz656488]# java -cp  "$QPID_DEPS$LOG4J:$QPID_JARS" ReplyToTest
  Jan 19, 2011 3:17:19 AM org.apache.qpid.client.AMQConnection <init>
  INFO: Connection:amqp://guest:********@clientID/test?brokerlist='tcp://localhost:5672?heartbeat='120''
  Jan 19, 2011 3:17:20 AM org.apache.qpid.client.protocol.AMQProtocolSession <init>
  INFO: Using ProtocolVersion for Session:0-10
  Jan 19, 2011 3:17:20 AM org.apache.qpid.client.handler.ClientMethodDispatcherImpl newMethodDispatcher
  INFO: New Method Dispatcher:AMQProtocolSession[null]
  Jan 19, 2011 3:17:20 AM org.apache.qpid.client.AMQConnection <init>
  INFO: Connecting with ProtocolHandler Version:0-10
  Jan 19, 2011 3:17:20 AM org.apache.qpid.client.AMQConnection <init>
  INFO: Connected with ProtocolHandler Version:0-10
  Jan 19, 2011 3:17:20 AM org.apache.qpid.client.AMQSession <init>
  INFO: Created session:org.apache.qpid.client.AMQSession_0_10@112e7f7
  Jan 19, 2011 3:17:20 AM org.apache.qpid.client.AMQSession registerConsumer
  INFO: Prefetching delayed existing messages will not flow until requested via receive*() or setML().
  Jan 19, 2011 3:17:20 AM org.apache.qpid.client.BasicMessageProducer setPublishMode
  INFO: MessageProducer org.apache.qpid.client.BasicMessageProducer_0_10@1c5466b using publish mode : ASYNC_PUBLISH_ALL
  Jan 19, 2011 3:17:20 AM org.apache.qpid.client.AMQSession startDispatcherIfNecessary
  INFO: Dispatcher-Channel-1 created
  Jan 19, 2011 3:17:20 AM org.apache.qpid.client.AMQSession$Dispatcher run
  INFO: Dispatcher-Channel-1 started
  java.lang.NullPointerException
          at org.apache.qpid.client.message.AbstractAMQMessageDelegate.generateDestination(AbstractAMQMessageDelegate.java:98)
          at org.apache.qpid.client.message.AMQMessageDelegate_0_10.getJMSReplyTo(AMQMessageDelegate_0_10.java:224)
          at org.apache.qpid.client.message.AbstractJMSMessage.getJMSReplyTo(AbstractJMSMessage.java:133)
          at ReplyToTest.main(ReplyToTest.java:48)
  [root@mrg-qe-07 bz656488]# rpm -qa | grep qpid | grep java
  qpid-java-example-0.7.946106-14.el4.noarch
  qpid-java-client-0.7.946106-14.el4.noarch
  qpid-java-common-0.7.946106-14.el4.noarch

Comment 8 Rajith Attapattu 2011-01-19 22:23:18 UTC
The NPE reported above is a different issue than the one described in the original description.

The original NPE happens due to the replyTo containing Null for the exchange or routing key.

The subsequent NPE reported by Frantisek is due to the JMS client not having information in it's internal map with regards to the custom exchange created for the reply-to destination.

Ex. "hello;{create:always,node:{type:topic}}"

I am currently testing a potential fix for this issue and will post the details once finalized.

Comment 9 Frantisek Reznicek 2011-01-21 08:13:51 UTC
Thanks for explanation Rajith,
could you possibly attach the reproducer for the original issue, please?

I was trying hard to reproduce the described way, but I was not triggering that. Reliable reproducer of the original issue would help me a lot quickly finish this defect.

Comment 10 Rajith Attapattu 2011-01-28 02:59:50 UTC
The second issue described in comment #8 is tracked in upstream via QPID-3011
A fix was committed at rev 1061577 in Qpid trunk.

Ported the fix to the internal git repo
http://mrg1.lab.bos.redhat.com/cgit/qpid.git/commit/?h=mrg_1.3.0.x&id=aa71c08f986b3485584c7e610d6e26866483fe4a

Comment 11 Rajith Attapattu 2011-01-28 14:58:12 UTC
The fixes have been incorporated into qpid-java-0.7.946106-15

Comment 12 Rajith Attapattu 2011-01-29 00:57:24 UTC
Created attachment 475904 [details]
Reproducer for both issues

Hi Frantisek,

The attach java program can test for both issues.

1. Nameless exchange used in replyTo - the cause of the first NPE reported by Mike.

2. A custom exchange used in replyTo - the cause of the NPE reported by you.

Please note the program will not compile unless you uncomment the option you want to test.

Please let me know if you have any questions.

Regards,

Rajith

Comment 13 Frantisek Reznicek 2011-02-02 15:54:30 UTC
The issues (both, original 1. and later one 2. ) have been fixed, tested on RHEL 4.9beta / 5.6,  i386 / x86_64 on packages:

qpid-java-client-0.7.946106-15.el5
qpid-java-common-0.7.946106-15.el5
qpid-java-example-0.7.946106-15.el5
python-qpid-0.7.946106-15.el5
qpid-cpp-client-0.7.946106-27.el5
qpid-cpp-client-devel-0.7.946106-27.el5
qpid-cpp-client-devel-docs-0.7.946106-27.el5
qpid-cpp-client-ssl-0.7.946106-27.el5
qpid-cpp-mrg-debuginfo-0.7.946106-27.el5
qpid-cpp-server-0.7.946106-27.el5
qpid-cpp-server-cluster-0.7.946106-27.el5
qpid-cpp-server-devel-0.7.946106-27.el5
qpid-cpp-server-ssl-0.7.946106-27.el5
qpid-cpp-server-store-0.7.946106-27.el5
qpid-cpp-server-xml-0.7.946106-27.el5
qpid-tools-0.7.946106-12.el5


-> VERIFIED


Note You need to log in before you can comment on or make changes to this bug.