I forced the nightly release job to run a little early, you should now find binaries with the change included at: https://builds.apache.org/view/M-R/view/Qpid/job/Qpid-Java-Artefact-Release/lastSuccessfulBuild/artifact/trunk/qpid/java/amqp-1-0-client-jms/release/
Alternatively you can use the maven artefacts from the snapshots repo at: https://repository.apache.org/content/repositories/snapshots/ <dependency> <groupId>org.apache.qpid</groupId> <artifactId>qpid-amqp-1-0-client-jms</artifactId> <version>0.28-SNAPSHOT</version> </dependency> Robbie On 19 February 2014 20:53, Rob Godfrey <[email protected]> wrote: > 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. > >>> >> > >>> > >> > >> > > >
