Hi Rob,
Here is the stack trace. The line (72) in Listener.java (app code) that is
failing is just:
messageProducer2.send(msg);
where messageProducer2 is a MessageProducer from the Qpid connection/session,
and msg is just a “Message” which was received from Q1 just prior, via the
Openwire transport (from its own connection/session).
javax.jms.JMSException: Unresolvable destination:
org.apache.qpid.amqp_1_0.jms.impl.QueueImpl.isQueue():
org.apache.qpid.amqp_1_0.jms.impl.QueueImpl@706254aa
at
org.apache.activemq.command.DefaultUnresolvedDestinationTransformer.transform(DefaultUnresolvedDestinationTransformer.java:48)
at
org.apache.activemq.command.ActiveMQDestination.transform(ActiveMQDestination.java:132)
at
org.apache.activemq.command.ActiveMQMessage.setJMSDestination(ActiveMQMessage.java:243)
at
org.apache.qpid.amqp_1_0.jms.impl.MessageProducerImpl.send(MessageProducerImpl.java:309)
at
org.apache.qpid.amqp_1_0.jms.impl.MessageProducerImpl.send(MessageProducerImpl.java:215)
at Listener.main(Listener.java:72)
Is this enough to tell you what’s happening?
If not, please let me know what else I can provide to understand this issue!
I can include code. It’s only for testing purposes anyway.
Thanks,
Mark.
Sent from my iPhone
> On Feb 19, 2014, at 1:51, Rob Godfrey <[email protected]> wrote:
>
> Hi Mark,
>
>> On 19 February 2014 05:23, Mark Barker <[email protected]> wrote:
>>
>> Thanks again to Rob and Robbie for their answers thus far!
>>
>> So I managed to slap (i.e. Frankenstein) together two pieces of
>> example/client code in order to attempt to facilitate a bridge of sorts
>> between two disparate queues.
>>
>> For this test, I'm using an ActiveMQ broker with two client processes/JVMs
>> (client1 and client2).
>> The ActiveMQ broker is configured with 2 active protocols (transport
>> connectors) - Openwire (standard) on port 61616, and AMQP (1.0) on port
>> 5673 (only because I was experimenting previously with the Qpid broker on
>> the more conventional port 5672) on the same box.
>>
>> client1 is a process based purely on an ActiveMQ Java/JMS openwire client
>> (Publisher.java) example and its only purpose is to publish a TextMessage
>> into Q1 via the openwire (tcp://) connection URL.
>>
>> client2 contains client code (and is linked/run with .jar libraries) for
>> both ActiveMQ AND Qpid JMS (AMQP 1.0). Its intent is to read messages from
>> Q1 (via ActiveMQ) and re-deliver them into Q2 (via AMQP). This situation is
>> a little contrived to start with, as eventually Q2 may well be on a
>> physically separate broker on a physically separate machine.
>>
>> So far, so good. I did some basic testing and proved my single client2
>> process can successfully (independently) interact with both queues (via
>> both protocols).
>>
>> My issue is now this:
>> If I receive a "TextMessage" in client2 using "consumer2" (a
>> MessageConsumer for the ActiveMQ connection/session), this message
>> object/entity ("msg") is not just something I can use (unaltered) to "send"
>> via client2's "producer2" (a MessageProducer for the AMQP
>> connection/session). Indeed, if I just try and "producer2.send(msg)", I get
>> a Java exception at runtime. Something like:
>> "javax.jms.JMSException: Unresolvable destination:
>> org.apache.qpid.amqp_1_0.jms.impl.QueueImpl.isQueue():
>> org.apache.qpid.amqp_1_0.jms.impl.QueueImpl@e127d8ab" on the "send" call.
>>
>> I can only assume that this is because TextMessage has 2 separate
>> implementations context-dependant on the protocol/client interface with
>> which we are dealing.
>> Some digging (printing out the .getClass() results) shows that the msg
>> received is something like an
>> org.apache.activemq.command.ActiveMQTextMessage,
>> and the message needed to be sent is actually an
>> org.apache.qpid.amqp_1_0.jms.impl.TestMessageImpl.
>>
>> If this is the case, what is the best way to solve this problem.
>> If msg has a number of header and application-defined property attributes
>> (never minding the body), how exactly is client2 supposed to copy/preserve
>> them all across into a TextMessage object implementation suitable for
>> delivery to Q2. Will client2 need to know the exact structure of the
>> messages in order to deconstruct and reconstruct to satisfy the protocol
>> bridging??
>
> So, in general a JMS library should be able to send a valid JMS message
> created or received from a different JMS provider... these are known as
> "foreign" messages in JMS terms. The exception is that Destinations (such
> as those found in the JMSReplyTo field) are provider specific. However if
> you don't have a ReplyTo set in the incoming message then I don't believe
> there should be any other issues as long as the messages are conformant
> with the JMS specification (note that many providers may "extend" the JMS
> specification to allow for non standard behaviours such as allowing map
> messages to contain nested maps or lists... such messages cannot be
> guaranteed to be resent without issue).
>
> Having said all of the above, I'm not sure that this is actually your
> issue... the error you are seeing sounds more like it is to do with trying
> to send to a queue which doesn't exist, however I can't find the error text
> you pasted in the Qpid codebase anywhere... Would it be possible to paste
> in the complete stack trace (or at least all the bits that are within the
> qpid code if you want to remove any confidential parts from your own
> program)?
>
> Thanks,
> Rob
>
>
>> As ever, any help with this would be hugely appreciated...
>> Thanks in advance,
>> Mark.
>>
>>
>> -----Original Message----- From: Rob Godfrey
>> Sent: Monday, February 17, 2014 5:54 PM
>>
>> To: [email protected]
>> Subject: Re: New User JMS API Questions
>>
>> On 18 February 2014 01:11, Mark Barker wrote:
>>
>> Robbie,
>>> thanks again for your answers.
>>>
>>> As for your first suggestion:
>>>
>>> "connecting an ActiveMQ JMS client to the ActiveMQ
>>> broker and a Qpid JMS client to the Qpid broker within the same JVM"
>>>
>>> Is this going to be possible in practice? I'm something of a novice at
>>> Java too. Will there be some kind of conflict if trying to use both the
>>> ActiveMQ JMS client and the Qpid JMS client APIs in the same process? How
>>> would/could this be done (example build command)? Thus far I have been
>>> building simple example code from the command line and referencing the
>>> relevant .jar dependency in the classpath params for both javac (build)
>>> and
>>> java (runtime).
>>>
>>>
>>> There shouldn't be an issue as long as there are no conflicts between the
>> dependencies of the ActiveMQ client and the Qpid client. The Qpid clients
>> aim to have as few dependencies as possible, so there really shouldn't be
>> an issue.
>>
>>
>> Finally,
>>> today I've been looking at getting the simple Hello.java example running
>>> on the ActiveMQ broker.
>>> Obviously, this means I have to use a JMS AMQP 1.0 client, so I've been
>>> using the Qpid JMS 1.0 client.
>>> I've encountered some issues which seem to relate to the Connection URL
>>> syntax from the JNDI (hello.properties) file.
>>>
>>> For instance,
>>> in a previous Qpid client talking AMQP 0-10 with a Qpid broker, I used:
>>> amqp://username:password@clientid/test?brokerlist='tcp://localhost:5672'
>>> however I've read and seen in practice that this won't work with the 1.0
>>> client.
>>> Instead I have to use something like:
>>> amqp://username:password@localhost:5672
>>>
>>> Can somebody please point me to the relevant documentation that explains
>>> this difference in syntax. For all my digging on the Qpid website, I can
>>> only find examples of the first/former (0-10 style), with no disclaimers
>>> or
>>> caveats regarding the 1.0 client.
>>>
>>>
>>> No - there isn't a lot (or indeed really any) documentation around the
>> AMQP
>> 1.0 client. As you've noted the syntax is a little different from the 0-10
>> style... but you've pretty much got all of the syntax already.
>>
>> There are currently a number of options (set in the normal URI way:
>> amqp://username:password@host:port?option1=value1&option2=value2...) to
>> fine tune some AMQP settings. If you are interested you can look in the
>> code which parses them here:
>>
>> https://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-
>> client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/
>> ConnectionFactoryImpl.java?revision=1557982&view=markup&pathrev=1568703
>>
>> Between lines 295 and 381 you will see the available options defined along
>> with a brief description of their purpose.
>>
>>
>> In addition, I've found I can use "queue://" or "topic://" prefixes in the
>>> JNDI properties to specify the object type when using the generic
>>> interface
>>> (i.e. general instead of p2p/pub-sub). Is that syntax a feature of the
>>> AMQP
>>> protocol, or something specific to the Qpid client or ActiveMQ broker? I
>>> can't find much mention of it anywhere.
>>>
>>>
>>> That's something specific to the ActiveMQ broker.
>>
>>
>> Thanks again for giving these questions your attention!!
>>>
>>>
>>>
>>> -- Rob
>>
>>
>>
>>> -----Original Message----- From: Robbie Gemmell
>>> Sent: Saturday, February 15, 2014 2:57 PM
>>>
>>> To: [email protected]
>>> Subject: Re: New User JMS API Questions
>>>
>>> On 14 February 2014 04:55, Mark Barker wrote:
>>>
>>> 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?
>>> It sounds like you are talking about bridging two brokers, which you
>>> presumably do either by connecting an ActiveMQ JMS client to the ActiveMQ
>>> broker and a Qpid JMS client to the Qpid broker within the same JVM, or by
>>> using the Qpid AMQP 1.0 JMS client to connect to both brokers.
>>