Bug 672212

Summary: Qpid java client NullPointer Exception in BasicMessageProducer_0_10 when specified address does not exist
Product: Red Hat Enterprise MRG Reporter: Frantisek Reznicek <freznice>
Component: qpid-javaAssignee: Rajith Attapattu <rattapat+nobody>
Status: CLOSED CURRENTRELEASE QA Contact: Frantisek Reznicek <freznice>
Severity: high Docs Contact:
Priority: high    
Version: 1.3CC: esammons, gsim, iboverma
Target Milestone: 1.3.2-RC2   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: qpid-java-0.7.946106-15 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Frantisek Reznicek 2011-01-24 12:29:24 UTC
Description of problem:

When an (transactional) transmission java client tries to send messages to address which does not exist, then clients ends with java.lang.NullPointerException in BasicMessageProducer_0_10.java:165:

[root@dhcp-26-233 bz667428]# java -cp "$QPID_DEPS$LOG4J:$QPID_JARS" TxSender0
log4j:WARN No appenders could be found for logger (org.apache.qpid.jndi.PropertiesFileInitialContextFactory).
log4j:WARN Please initialize the log4j system properly.
Sending message: message
Exception occurred: java.lang.NullPointerException
java.lang.NullPointerException
        at org.apache.qpid.client.BasicMessageProducer_0_10.sendMessage(BasicMessageProducer_0_10.java:165)
        at org.apache.qpid.client.BasicMessageProducer.sendImpl(BasicMessageProducer.java:490)
        at org.apache.qpid.client.BasicMessageProducer.sendImpl(BasicMessageProducer.java:445)
        at org.apache.qpid.client.BasicMessageProducer.send(BasicMessageProducer.java:283)
        at TxSender0.main(TxSender0.java:28)


This behavior was seen on RHEL5.6 x86_64 when client was ran on single cluster node with configuration:
cluster-mechanism=ANONYMOUS
cluster-name=freznice-virt-cluster
log-enable=info+
log-to-file=/tmp/qpidd.log
mgmt-pub-interval=1


Version-Release number of selected component (if applicable):
qpid-cpp-client-devel-0.7.946106-27.el5
qpid-java-client-0.7.946106-14.el5
qpid-cpp-server-0.7.946106-27.el5
qpid-cpp-server-cluster-0.7.946106-27.el5
qpid-cpp-mrg-debuginfo-0.7.946106-26.el5
qpid-java-common-0.7.946106-14.el5
qpid-cpp-server-xml-0.7.946106-27.el5
qpid-tools-0.7.946106-12.el5
qpid-cpp-client-ssl-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-devel-0.7.946106-27.el5
qpid-cpp-client-0.7.946106-27.el5
qpid-java-example-0.7.946106-14.el5
python-qpid-0.7.946106-15.el5
qpid-cpp-client-devel-docs-0.7.946106-27.el5


How reproducible:
100%

Steps to Reproduce:
1. start broker (standalone or clustered)
2. compile the attached client
3. execute the attached client
  
Actual results:
Qpid java client exits with java.lang.NullPointerException.

Expected results:
Qpid java client should exit with an 'address not exists exception'

Additional info:
QPID_DEPS=`find /usr/share/java/qpid-deps/*.jar | tr '\n' ":"`
QPID_JARS=`find /usr/share/java -name 'qpid-client*.jar' -or -name 'qpid-common*.jar' | tr '\n' ":"`
LOG4J="/usr/share/java/log4j.jar"

[root@dhcp-26-233 bz667428]# javac -cp "$QPID_DEPS$LOG4J:$QPID_JARS" TxSender0.java
[root@dhcp-26-233 bz667428]# java -cp "$QPID_DEPS$LOG4J:$QPID_JARS" TxSender0
log4j:WARN No appenders could be found for logger (org.apache.qpid.jndi.PropertiesFileInitialContextFactory).
log4j:WARN Please initialize the log4j system properly.
Sending message: message
Exception occurred: java.lang.NullPointerException
java.lang.NullPointerException
        at org.apache.qpid.client.BasicMessageProducer_0_10.sendMessage(BasicMessageProducer_0_10.java:165)
        at org.apache.qpid.client.BasicMessageProducer.sendImpl(BasicMessageProducer.java:490)
        at org.apache.qpid.client.BasicMessageProducer.sendImpl(BasicMessageProducer.java:445)
        at org.apache.qpid.client.BasicMessageProducer.send(BasicMessageProducer.java:283)
        at TxSender0.main(TxSender0.java:28)
[root@dhcp-26-233 bz667428]# cat TxSender0.java
import javax.jms.*;
import javax.naming.*;
import java.util.Properties;

public class TxSender0 {

    public static void main(String[] args) {
        try {
            String connectionUrl = "amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672'";
            String address = "my-queuE";

            Properties props = new Properties();
            props.setProperty("java.naming.factory.initial", "org.apache.qpid.jndi.PropertiesFileInitialContextFactory");
            props.setProperty("connectionfactory.host", connectionUrl);
            props.setProperty("destination.address", address);

            Context ctx = new InitialContext(props);
            ConnectionFactory factory = (ConnectionFactory) ctx.lookup("host");
            Destination target = (Destination) ctx.lookup("address");

            Connection conn = factory.createConnection();
            Session session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
            MessageProducer sender = session.createProducer(target);
            TextMessage message = session.createTextMessage();

            message.setText("message");
            System.out.println("Sending message: " + message.getText());
            sender.send(message);

            session.commit();
            System.out.println("Committed ");

        } catch (Exception e) {
            System.out.println("Exception occurred: " + e.toString());
            e.printStackTrace();
        }
    }
}

Comment 1 Frantisek Reznicek 2011-01-24 12:31:03 UTC
The transactional client is not the key as I can see similar the behavior with org.apache.qpid.example.Spout example:

[root@dhcp-26-233 bz667428]# cd /usr/share/doc/qpid-java-0.7.946106/examples
[root@dhcp-26-233 examples]# ./run_example.sh org.apache.qpid.example.Spout "ADDRq"
{}
main 2011-01-24 13:27:45,611 WARN [apache.qpid.client.BasicMessageProducer_0_10] Exception occured while verifying destination
org.apache.qpid.AMQException: The name 'ADDRq' supplied in the address doesn't resolve to an exchange or a queue
        at org.apache.qpid.client.AMQSession_0_10.handleAddressBasedDestination(AMQSession_0_10.java:1232)
        at org.apache.qpid.client.BasicMessageProducer_0_10.declareDestination(BasicMessageProducer_0_10.java:81)
        at org.apache.qpid.client.BasicMessageProducer.<init>(BasicMessageProducer.java:141)
        at org.apache.qpid.client.BasicMessageProducer_0_10.<init>(BasicMessageProducer_0_10.java:60)
        at org.apache.qpid.client.AMQSession_0_10.createMessageProducer(AMQSession_0_10.java:663)
        at org.apache.qpid.client.AMQSession_0_10.createMessageProducer(AMQSession_0_10.java:82)
        at org.apache.qpid.client.AMQSession$6.execute(AMQSession.java:2404)
        at org.apache.qpid.client.AMQSession$6.execute(AMQSession.java:2399)
        at org.apache.qpid.client.AMQConnectionDelegate_0_10.executeRetrySupport(AMQConnectionDelegate_0_10.java:278)
        at org.apache.qpid.client.AMQConnection.executeRetrySupport(AMQConnection.java:765)
        at org.apache.qpid.client.failover.FailoverRetrySupport.execute(FailoverRetrySupport.java:102)
        at org.apache.qpid.client.AMQSession.createProducerImpl(AMQSession.java:2397)
        at org.apache.qpid.client.AMQSession.createProducerImpl(AMQSession.java:2391)
        at org.apache.qpid.client.AMQSession.createProducer(AMQSession.java:1054)
        at org.apache.qpid.client.AMQSession.createProducer(AMQSession.java:95)
        at org.apache.qpid.example.Spout.<init>(Spout.java:91)
        at org.apache.qpid.example.Spout.main(Spout.java:146)
Exception in thread "main" java.lang.NullPointerException
        at org.apache.qpid.client.BasicMessageProducer_0_10.sendMessage(BasicMessageProducer_0_10.java:165)
        at org.apache.qpid.client.BasicMessageProducer.sendImpl(BasicMessageProducer.java:490)
        at org.apache.qpid.client.BasicMessageProducer.sendImpl(BasicMessageProducer.java:445)
        at org.apache.qpid.client.BasicMessageProducer.send(BasicMessageProducer.java:283)
        at org.apache.qpid.example.Spout.<init>(Spout.java:98)
        at org.apache.qpid.example.Spout.main(Spout.java:146)

Comment 3 Rajith Attapattu 2011-01-25 03:53:22 UTC
Bug Analysis
-------------
The real underlying issue here is that an exception is not thrown when constructing the MessageProducer with an invalid destination.

The address validation code does throw an exception, but it's merely logged and not propagated up the stack.

Proposed Solution
-----------------
This issue is tracked in upstream via QPID-3019 and is fixed in rev 1063123 in Qpid trunk.

The commit contains the following,

1. Modified the createMessageProducer methods (in AMQSession/AMQSession_0
_10/AMQSession_0_8) to throw JMSException

2. Modified the constructors in BasicMessageProducer (0-10 & 0-8 classes) to throw AMQException

3. Added error handling code in BasicMessageProducer_0_10.java constructor to catch and report exceptions from the address validation code.

Impact From Proposed Solution
------------------------------
* All changes are minor additions to improve error handling. It involves throwing exceptions up the stack and/or catching an exception and rethrowing after encapsulating in a JMS Exception.

* The changes only affect the creation of a producer and has no bearing on any other functionality.

Comment 7 Rajith Attapattu 2011-01-28 03:55:54 UTC
This issue is tracked in upstream via QPID-3019
A fix was committed at rev 1063123 in Qpid trunk.

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

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

Comment 8 Rajith Attapattu 2011-01-28 14:57:38 UTC
The fixes have been incorporated into qpid-java-0.7.946106-15

Comment 9 Frantisek Reznicek 2011-02-01 13:20:07 UTC
The issue has been fixed, tested on RHEL 4.9beta, RHEL 5.6 on packages:
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-java-client-0.7.946106-15.el5
qpid-java-common-0.7.946106-15.el5
qpid-java-example-0.7.946106-15.el5
qpid-tools-0.7.946106-12.el5

The current package set ends in above described case with reasonable exception:

Exception in thread "main" javax.jms.JMSException: Error creating producer
        at org.apache.qpid.client.AMQSession_0_10.createMessageProducer(AMQSession_0_10.java:670)
        at org.apache.qpid.client.AMQSession_0_10.createMessageProducer(AMQSession_0_10.java:82)
        at org.apache.qpid.client.AMQSession$6.execute(AMQSession.java:2404)
        at org.apache.qpid.client.AMQSession$6.execute(AMQSession.java:2399)
        at org.apache.qpid.client.AMQConnectionDelegate_0_10.executeRetrySupport(AMQConnectionDelegate_0_10.java:278)
        at org.apache.qpid.client.AMQConnection.executeRetrySupport(AMQConnection.java:765)
        at org.apache.qpid.client.failover.FailoverRetrySupport.execute(FailoverRetrySupport.java:102)
        at org.apache.qpid.client.AMQSession.createProducerImpl(AMQSession.java:2397)
        at org.apache.qpid.client.AMQSession.createProducerImpl(AMQSession.java:2391)
        at org.apache.qpid.client.AMQSession.createProducer(AMQSession.java:1054)
        at org.apache.qpid.client.AMQSession.createProducer(AMQSession.java:95)
        at org.apache.qpid.example.Spout.<init>(Spout.java:91)
        at org.apache.qpid.example.Spout.main(Spout.java:146)
Caused by: org.apache.qpid.AMQException: Exception occured while verifying destination
        at org.apache.qpid.client.BasicMessageProducer_0_10.declareDestination(BasicMessageProducer_0_10.java:86)
        at org.apache.qpid.client.BasicMessageProducer.<init>(BasicMessageProducer.java:141)
        at org.apache.qpid.client.BasicMessageProducer_0_10.<init>(BasicMessageProducer_0_10.java:61)
        at org.apache.qpid.client.AMQSession_0_10.createMessageProducer(AMQSession_0_10.java:665)
        ... 12 more
Caused by: org.apache.qpid.AMQException: The name 'XXXHhjhjhjhd' supplied in the address doesn't resolve to an exchange or a queue
        at org.apache.qpid.client.AMQSession_0_10.handleAddressBasedDestination(AMQSession_0_10.java:1243)
        at org.apache.qpid.client.BasicMessageProducer_0_10.declareDestination(BasicMessageProducer_0_10.java:82)
        ... 15 more


-> VERIFIED