OK, I've checked in a change to the trunk codebase so that the Qpid
DestinationImpl object no longer implements javax.jms.Queue and
javax.jms.Topic interfaces... I think this should help ActiveMQ to cope
with it...

If you want to test this you'll need to check out the source code from here:

http://svn.apache.org/repos/asf/qpid/trunk/qpid/

Go to the java subdirectory, and build using ant (e.g. "ant build").  The
built libraries will then be in the build/lib subdirectory (you'll only
want the amqp-1-0-*0.27.jar files).

Let me know if you manage to get it working or encounter any more issues.


Cheers,

Rob


and


On 19 February 2014 21:42, Rob Godfrey <[email protected]> wrote:

> 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 <[email protected]> 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 <[email protected]> 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 <[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.
>>> >>
>>>
>>
>>
>

Reply via email to