OK... looking up their code tree a bit I see why it gets confused by the
Qpid destination... because the Qpid AMQP 1.0 DestinationImpl implements
both Queue and Topic... I'm not sure why it does that (probably a
historical artefact).  If I change that in Qpid, it might make ActiveMQ
happier...

-- Rob


On 19 February 2014 21:10, Rob Godfrey <rob.j.godf...@gmail.com> wrote:

> Ah interesting... it's ActiveMQ code that is throwing the exception... As
> per the JMS contract, the Qpid message producer is setting the
> JMSDestination on the message it is sending (in this case a foreign
> message, namely an ActiveMQ message).  The ActiveMQ message class doesn't
> seem to like having a destination set on it which isn't one that it can
> resolve (even though it doesn't need to).  The code in question appears to
> be here in the activeMQ codebase:
>
>
> http://grepcode.com/file/repo1.maven.org/maven2/org.apache.activemq/activemq-core/5.6.0/org/apache/activemq/command/DefaultUnresolvedDestinationTransformer.java
>
> It looks like ActiveMQ is requiring Queue and Topic implementations to
> implement the methods isQueue() and/or isTopic()... but these are not part
> of the API defined for JMS Queues and topics AFAIK (see
> http://docs.oracle.com/javaee/6/api/javax/jms/Queue.html for example).
>  So I think that ActiveMQ is in error / violation of the JMS spec here
> (though Robbie who has been reading the JMS spec carefully lately may be
> able to give better advice).  If ActiveMQ is absolutely determined to turn
> the destination object into an ActiveMQ one, I'm not entirely sure why the
> ActiveMQ code doesn't fall back to an instanceof test to determine whether
> the the passed in Destination is a Queue (or if not a Topic)...
>
> -- Rob
>
>
> On 19 February 2014 20:01, Mark Barker <mark.bar...@shaw.ca> wrote:
>
>> 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 <rob.j.godf...@gmail.com> wrote:
>> >
>> > Hi Mark,
>> >
>> >> On 19 February 2014 05:23, Mark Barker <mark.bar...@shaw.ca> 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: users@qpid.apache.org
>> >> 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: users@qpid.apache.org
>> >>> 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.
>> >>
>>
>
>

Reply via email to