qpid-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Mark Barker" <mark.bar...@shaw.ca>
Subject Re: New User JMS API Questions
Date Fri, 14 Feb 2014 04:55:01 GMT
Thanks Robbie, that was a very helpful collection of useful insights - I 
don't think I would have found or understood these points just by reading 
around the web and docs!!

FYI, my initial attempt at contributing to this list from my work email 
account was doomed to failure as our work filters are blocking the list 
subscription responses to which we need to reply in order to join in the 
first place - hence my using my home account as the fallback.

There are definitely some gems in those answers that help me better 
understand what's going on under the covers in the Qpid JMS implementation 
so thank you very much for taking the time to answer those points. By the 
way, your point in your answers about moving the getTopicName() call 
somewhat worked. When I moved it down a couple of lines as you suggested for 
the first test specifying destination.topicExchange, the call no longer 
returned 'null', but instead returned what seemed to be the binding key for 
that scenario - i.e. '#'. In that way, it matches the topic.topicExchange 
test, in which the same call returned "news-service2" which in that case was 
the binding key there also.

So it looks like the next tranche of effort will involve looking at the 
possibilities of using JMS/Qpid clients/brokers in combination with ActiveMQ 
I guess my main worry/concern before starting this exercise is just how 
feasible this endeavour will be.
>From what I understand, ActiveMQ is currently only compatibile with AMQP 
1.0, correct?

If anyone has a tried this, or can confirm:
will it be possible to have a JMS client using an ActiveMQ broker on one 
machine (or maybe a producer/consumer pair), ultimately sending a message 
which then routes to a Qpid broker and associated local JMS consumer on a 
second machine (preserving all standard and application-specific JMS message 
headers/properties). Has this been done and are there further tricks, 
considerations and caveats here?
Maybe the ActiveMQ JMS consumer process on the first machine makes the 
routing decision and then places the message via a producer instance for the 
Qpid broker on the 2nd machine? Or maybe it would be possible to 
administratively configure the 2 brokers to be linked in a manner similar to 
what I've been reading about Federations of brokers??

Finally, does anyone know if it is possible to integrate a Qpid broker into 
an ActiveMQ 'cluster' configuration?? From the very brief reading I've done, 
it appears the Qpid cluster implementation may be somewhat different in its 

Thanks once again for all the help as I get to grips with this new subject 


-----Original Message----- 
From: Robbie Gemmell
Sent: Wednesday, February 12, 2014 11:09 AM
To: users@qpid.apache.org
Subject: Re: New User JMS API Questions

Hi Mark,

Is your work email address registered on the list? if not the message may
be awaiting moderation.

Part of the issue is that you are definitely tripping up on a mixture of
JNDI configuration, some of which is of the newer 'Address' syntax variety
and some which is of the older 'Binding URL' format supported by the JMS
On top of that, you may be getting confused by the use of 'topic' as the
type of an AMQP 0-x exchange, and the name of a node type in the 'Address'
syntax supported by the various Qpid clients, and finally its use in JMS
and differing behaviour of the client depending on the syntax in use.

On the terminology side:

The 'topic' type of exchanges in AMQP 0-X support pattern matching for
routing, whereas the other exchange types don't. The 'Address' syntax uses
the 'topic' to describe a node that can provide pub-sub semantics, and in
the case of AMQP 0-10 that is taken to mean an exchange ~(of any type) with
the name of the topic. The JMS client uses 'topic' in essentially the same
way when using the 'Address' syntax, but with the 'Binding URL' syntax the
topic name is used as the routing key when publishing the message to a
particular exchange (whose name may be unrelated to the topic name, and
usually is) or binding queues to the exchange to recieve messages.

On the JMS client behaviour side:

JNDI properties of the form "destination.<lookupname> = <value>" are
treated as 'Address' strings by default, but may be treated as BindingURLs
if desired (see at the bottom). "queue.<lookupname> = <value>" and
"topic.<lookupname> = <value>" values in the JNDI file are treated as a
shorthand form of BindingURL that results in Queue usage with bindings and
publications to the amq.direct exchange using the queue name as the key,
and Topic usage with bindings and publications to the amq.topic exchange
using the topic name as the key.

In your first test, by specifying "destination.topicExchange =
news-service2" you thus got an 'Address' based Destination. The client
'resolves' the Address string against the broker when you create your
producer/consumer to determine if the address is actually for a queue or a
topic (i.e an exchange) node. Prior to that it is returning null from the
'getTopicName' method, whereas looking at the code I expect it would return
you the exchange name if you move that line down bit.

On your second test, by using "topic.topicExchange = news-service2" you
ended up with a BindingURL based Destination, which in this case told the
client to use the "amq.topic" exchange and send the messages with a routing
key of "news-service2", and to bind a temporary queue to amq.topic with the
binding key "new-service2".

For your third test, using "queue.topicExchange = some_queue_name" got you
a BindingURL based Destination, which told the client to use the
"amq.direct" exchange and send the messages with a routing key of
"some_queue_name". The consumer creation had the side effect of creating
the queue and binding it ot the amq.direct exchange, because you were using
a BindingURL based destination an this is the historic consumer behaviour
the client had with that syntax. For the Address syntax, it doesnt do that
by default but you can make it do something similar using the options of
the Address string.

Some other info:

You can see more details of the Address syntax at the following location,
though it is more tailored to the C++ etc APIs and the JMS client doesn't
necessarily support all of the options in the same way:

Some details of the expanded BindingURL format usable in the "destination."
JNDI entries is at:

You can change the clients default syntax at a client level by setting the
system property qpid.dest_syntax to the value BURL (or ADDR), or you can
prefix the <value> part of the JNDI property to override the default, using
BURL: to indicate a BindingURL, or ADDR: to indicate an Address.


On 12 February 2014 03:14, Mark Barker wrote:

> Apologies in advance if this shows up twice, but I seem to have had
> problems sending from my work account...
> ---
> Hello.
> I have been playing around with the Hello.java example that came with
> qpid-java-client-0.24.tar.gz.
> I have installed the qpidd package (the broker) on a Ubuntu 12.04 LTS
> platform along with the qpid-tools package
> (from the Ubuntu Software Centre).
> I am looking to try and integrate the Qpid broker with JMS-based clients.
> I am brand new to all of the concepts and my
> understanding is possibly being confused by the differences in terminology
> between JMS and Qpid elements.
> I would greatly appreciate if you can indulge a few questions arising from
> my initial foray...
> By modifying the code to use the pub/sub API, I have arrived at this
> source (Hello2.java):
> --------
> package org.apache.qpid.example;
> import javax.jms.*;
> import javax.naming.Context;
> import javax.naming.InitialContext;
> import java.util.Properties;
> public class Hello2
> {
>    public Hello2()
>    {
>   }
>    public static void main(String[] args)
>    {
>        Hello2 hello2 = new Hello2();
>        hello2.runTest();
>    }
>    private void runTest()
>    {
>        try {
>            Properties properties = new Properties();
>            properties.load(this.getClass().getResourceAsStream("hello2.
> properties"));
>            Context context = new InitialContext(properties);
>            TopicConnectionFactory topicConnectionFactory =
> (TopicConnectionFactory) context.lookup("qpidConnectionfactory");
>            TopicConnection topicConnection = topicConnectionFactory.
> createTopicConnection();
>            topicConnection.start();
>            TopicSession topicSession = 
> topicConnection.createTopicSession(false,
>            Topic topic = (Topic) context.lookup("topicExchange");
>            System.out.println(topic.getTopicName());
>            TopicPublisher topicPublisher = topicSession.createPublisher(
> topic);
>            TopicSubscriber topicSubscriber = 
> topicSession.createSubscriber(
> topic);
>            TextMessage message = topicSession.createTextMessage("Hello
> world!");
>            topicPublisher.publish(message);
>            message = (TextMessage)topicSubscriber.receive();
>            System.out.println(message.getText());
>            topicConnection.close();
>            context.close();
>        }
>        catch (Exception exp)
>        {
>            exp.printStackTrace();
>        }
>    }
> }
> --------
> Now, hello2.properties looks like this:
> --------
> java.naming.factory.initial = org.apache.qpid.jndi.
> PropertiesFileInitialContextFactory
> # register some connection factories
> # connectionfactory.[jndiname] = [ConnectionURL]
> connectionfactory.qpidConnectionfactory = amqp://guest:guest@clientid/?
> brokerlist='tcp://localhost:5672'
> # Register an AMQP destination in JNDI
> # destination.[jniName] = [Address Format]
> destination.topicExchange = news-service2
> #topic.topicExchange = news-service2
> --------
> Before running the program, I adminstratively create the topic exchange
> via qpid-config:
> % qpid-config add exchange topic news-service2
> Now... "AS-IS", the above code/properties combination "works" - i.e. when
> I compile and run Hello2.jar, I see this output:
> --------
> null
> Hello world!
> --------
> If I use the command-line "qpid-stat -e", I do indeed see msgIn and msgOut
> counters incrementing for the "news-service2"
> topic exchange.
> What I don't understand (my first question) here is why the
> "topic.getTopicName()" call is returning "null" in this instance?
> When I substitute "topic.topicExchange" for "destination.topicExchange" in
> the hello2.properties file, I get this output:
> --------
> news-service2
> Hello world!
> --------
> Here, "topic.getTopicName()" actually returns the expected string
> "news-service2".
> However, in this case "qpid-stat-e" shows that the corresponding topic
> exchange "news-service2" has NOT changed its
> msgIn/msgOut counters, BUT the counts for amq.topic have changed instead.
> My second question therefore is why have these
> messages ended up in amq.topic?
> A final question (more of a related query). If I use the default
> (original) example code Hello.java, but in hello.properties
> substitute "destination.topicExchange = amq.topic" for
> "queue.topicExchange = some_queue_name", I note that even if
> "some_queue_name" did not exist in the broker prior to running Hello, then
> it is created. This behaviour doesn't seem to work
> for "topic.topicExchange" so I was wondering why the discrepancy.
> Thanks for indulging these newbie questions!
> Mark.
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@qpid.apache.org
> For additional commands, e-mail: users-help@qpid.apache.org

To unsubscribe, e-mail: users-unsubscribe@qpid.apache.org
For additional commands, e-mail: users-help@qpid.apache.org

View raw message