Stomp message from PHP client, "Unsupported message type 'MapMessage'" from Java server

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Stomp message from PHP client, "Unsupported message type 'MapMessage'" from Java server

neek
Hi all,

I'm trying to integrate a traditional e-commerce website in PHP with my ActiveMQ java application.  What I thought would be a trivial test program has turned into a non-starter.  My main app runs a broker within a single VM, and has used the vm://localhost transport.  Now, I want to be able to send messages in to ActiveMQ from PHP, over either the tcp:// or stomp:// transport.

I've a very simple ActiveMQ test class which starts a broker and a consumer.  When my PHP client tries to send a MapMessage, the PHP sends without error but the Java server logs:

     [java] WARNING: Exception occurred processing:
     [java] SEND
     [java] amq-msg-type:MapMessage
     [java] transformation:jms-map-json
     [java] destination:/queue/integration/order_change
     [java] transformation-error:org/codehaus/jettison/mapped/Configuration
     [java]
     [java] {"map":{"orders_id":"1058","status":"1","comments":""}}: org.apache.activemq.transport.stomp.ProtocolException: Unsupported message type 'MapMessage'

The PHP then logs an error containing the same java stack trace, so the basic comms between PHP and Java seems to be working fine.  I'm pretty sure the error lies on the Java side, not the PHP side.

The "map": ... bit is the correct data that I sent from the PHP, but it seems to be rejected by the stomp transport.  From what I can see in the ActiveMQ 5.5.0 source code, org.apache.activemq.transport.stomp container support for MapMessages, and I got to this point by following documentation.  So, I wonder what's wrong?

The java server is a very simple class which starts a thread and starts a broker in it with:

BrokerService broker = BrokerFactory.createBroker(new URI("broker:stomp://localhost:61616"));
broker.start();

Do I need to do anything else to make the stomp transport be able to deal with MapMessages?

I don't think it matters how my consumer is set up on the Java side since the message is never hitting it.  It's identical to the way I set up a consumer in my main app, with java sending MapMessages to java within the same VM.

My PHP code looks like this:

try {
        $con = new Stomp("tcp://localhost:61616");
        // connect
        $con->connect();
        // send a message to the queue
        $body = array("map" => array("orders_id"=>$oID, "status"=>$status, "comments" => $comments));
        $header = array('transformation' => 'jms-map-json');
        $mapMessage = new Stomp_Message_Map($body, $header);
        $con->send("/queue/integration/order_change", $mapMessage, array());
        // subscribe to the queue
        $con->subscribe("/queue/test");
        // receive a message from the queue
        $msg = $con->readFrame();

        // do what you want with the message
        if ( $msg != null) {
                echo "Received message with body '$msg->body'\n";
                // mark the message as received in the queue
                $con->ack($msg);
        } else {
                error_log("Failed to receive a message");
        }
} catch (Stomp_Exception $e) {
        error_log("StompException sending message: " . $e->getMessage() .
                        " details: " . $e->getDetails());
}
// disconnect
$con->disconnect();

I got to this point by starting at http://activemq.apache.org/php.html, which links to two places.  I got the stompcli-php5-1.0-20080916.tar.gz  from the code.google.com site it links to, and built my PHP code using the documentation at http://stomp.fusesource.org/documentation/php/index.html.  There seems to be some mismatch between the two, for example the stompcli-php5 tarball contains a Stomp_Exception object but the documentation says to use StompException.

Also, the book at http://stomp.fusesource.org/documentation/php/book.html says to use tcp://localhost:61616 as the transport, but it seems that on the java side listening on tcp://localhost:61616 fails (with a "Transport failed: java.io.IOException: Unknown data type: 69" message) .. I must use stomp://localhost:61616 as the URI on the server to make it work at all.  Is the info at stomp.fusesource.org out of date or invalid in some way?

I've tried using the 1.0.0 client available from http://stomp.fusesource.org/download.html (which does define StompException and StompMapMessage) but it just seems to timeout when sending the message.  Their git repository URL doesn't respond for me so I cannot fetch their source that way.

Thank you for any help or advice,
Nick
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Stomp message from PHP client, "Unsupported message type 'MapMessage'" from Java server

neek
Incidentally, while the java side doesn't log a stack trace, the PHP side does when it reports the Stomp_Exception that is caught.  So, we can see the stack frame doesn't touch my code, it's all in org.apache.activemq.*:

message:
Unsupported message type 'MapMessage'

details:
org.apache.activemq.transport.stomp.ProtocolException: Unsupported message type 'MapMessage'
 at org.apache.activemq.transport.stomp.LegacyFrameTranslator.convertFrame(LegacyFrameTranslator.java:59)
 at org.apache.activemq.transport.stomp.JmsFrameTranslator.convertFrame(JmsFrameTranslator.java:92)
 at org.apache.activemq.transport.stomp.ProtocolConverter.convertMessage(ProtocolConverter.java:606)
 at org.apache.activemq.transport.stomp.ProtocolConverter.onStompSend(ProtocolConverter.java:241)
 at org.apache.activemq.transport.stomp.ProtocolConverter.onStompCommand(ProtocolConverter.java:178)
 at org.apache.activemq.transport.stomp.StompTransportFilter.onCommand(StompTransportFilter.java:70)
 at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
 at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:220)
 at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:202)
 at java.lang.Thread.run(Thread.java:662)
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Stomp message from PHP client, "Unsupported message type 'MapMessage'" from Java server

neek
I've made some progress.  Now I'm stumbling over the required format of the map message sent from PHP.  My various combinations of arrays are causing the xstream processing to throw exceptions and I can't figure out what I'm doing wrong yet.

For the record:

Getting the activemq source and telling Netbeans to use that as the 'source directory' for the jars I was running with allows me to set breakpoints in ActiveMQ and step through the code.  I had missed including jettison-1.2.jar on my classpath.  The code in JmsFrameTranslator:

                                case JMS_MAP_JSON:
                                        in = new JettisonMappedXmlDriver().createReader(new StringReader(text));
                                        msg = createMapMessage(in);
                                        break;

was throwing a NoClassDefFound exception for org/codehaus/jettison/mapped/Configuration in the call to createReader .. however, the catch block just below this code does this:

                        } catch (Throwable e) {
                                command.getHeaders().put(Stomp.Headers.TRANSFORMATION_ERROR, e.getMessage());
                                msg = super.convertFrame(converter, command);
                        }

This error message was not reaching me, so I had no idea a NoClassDefFound exception was happening.  Adding jettison-1.2.jar got me past the createReader() call.

However, the same "Unsupported message type 'MapMessage'" persisted, even when the unmarshalling was being attempted.  I managed to trace the java code to the lines in JmsFrameTranslator:

        protected ActiveMQMapMessage createMapMessage(HierarchicalStreamReader in) throws JMSException {
                ActiveMQMapMessage mapMsg = new ActiveMQMapMessage();
                Map<String, Object> map = (Map<String, Object>)getXStream().unmarshal(in);

This unmarshallaing is now throwing exceptions.

All this led me back to http://www.lancehendrix.com/techdocs/incubation/Talking%20Stomp%20to%20ActiveMQ.txt, which is verbose and hard to read but does contain working code.  It seems the exact format of the PHP array you have to send is very particular.

I might just fall back to sending a simple string of json encoded data and do the unmarshallaing myself.  Stepping through the xstream unmarshalling is really painful, all for the sake of sending a well formatted MapMessage.

Nick
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Stomp message from PHP client, "Unsupported message type 'MapMessage'" from Java server

hendrila
neek wrote
All this led me back to http://www.lancehendrix.com/techdocs/incubation/Talking%20Stomp%20to%20ActiveMQ.txt, which is verbose and hard to read but does contain working code.  It seems the exact format of the PHP array you have to send is very particular.
You might be interested in knowing that my site maintains a text and HTML version of all my pages.  The HTML version, while not any less verbose, might be easier to read: http://www.lancehendrix.com/techdocs/incubation/Talking%20Stomp%20to%20ActiveMQ.html

I am also in the process of updating this information as newer versions of ActiveMQ and the PHP stomp libraries make it easier to integrate (it worked out of the box for me for AMQ 5.5 and the Stomp 1.1 PHP library); however the PHP data structure required to make it work still seems to be the same.

Lance
Loading...