ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ Java / JMS » XML in JMSTextMessage or JMSBytesMessage

Post new topic  Reply to topic
 XML in JMSTextMessage or JMSBytesMessage « View previous topic :: View next topic » 
Author Message
sfari
PostPosted: Wed Oct 24, 2007 7:04 am    Post subject: XML in JMSTextMessage or JMSBytesMessage Reply with quote

Centurion

Joined: 15 Apr 2003
Posts: 144

Hello,

I am using two different WebService Products. Both of them are sending SOAP over MQ in different ways. So they are not interoperable

    - One product sends XML data within MQSTR messages (JMSTextMsg) setting the CCSID to the correct value (tests showed UTF-.

    - The other sends XML data within a Format less binary message (JMSBytesMsg).


We internally used to send XML over binary messages. Now I think that was not a very good idea, the way with the MQSTR and the correct CCSID looks quite resonable to me. What is the correct or better way?

Gruss
Silvano
Back to top
View user's profile Send private message
JLRowe
PostPosted: Wed Oct 24, 2007 12:06 pm    Post subject: Reply with quote

Yatiri

Joined: 25 May 2002
Posts: 664
Location: South East London

Use a TextMessage. JMS will use the MQSTR format and UTF-8 encoding.
Back to top
View user's profile Send private message Send e-mail
jefflowrey
PostPosted: Wed Oct 24, 2007 12:36 pm    Post subject: Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

XML is text.
_________________
I am *not* the model of the modern major general.
Back to top
View user's profile Send private message
sfari
PostPosted: Thu Oct 25, 2007 7:32 am    Post subject: Reply with quote

Centurion

Joined: 15 Apr 2003
Posts: 144

Yes I am just recognizing, that it seems to be the right way to use MQSTR.

The reason for using binary was to avoid any kind of unwanted code page translation.

So can you tell me, is it the only correct way to send XML via MQSTR?

Thanks for your answers!
Back to top
View user's profile Send private message
Vitor
PostPosted: Thu Oct 25, 2007 7:36 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

sfari wrote:
So can you tell me, is it the only correct way to send XML via MQSTR?


Unless you have packed data in a CDATA section. Which is not an especially good idea.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
Cyrille Le Clerc
PostPosted: Mon Nov 05, 2007 2:12 am    Post subject: Reply with quote

Novice

Joined: 23 May 2007
Posts: 12
Location: France

The javax.jms.Message javadoc states that the TextMessage should be used to send XML content :
Quote:
A TextMessage object's message body contains a java.lang.String object. This message type can be used to transport plain-text messages, and XML messages.


However, it is a bit paradoxical because a text message is a group of chars ; it does not deal with the encoding. Encoding is involved when you want to convert chars into bytes (e.g. to store/transport text messages in a file, a DB, a MOM message, etc).

On the other side, XML messages hold their encoding (<?xml version="1.0" encoding="UTF-8"?>) and thus should be seen as streams of bytes. We can see this in the java-xml apis. The javax.xml.transform.Result offers a StreamResult but no WriterResult.

So, what should we do with this 'beautiful' theory ?

First, add a javax.jms.XmlMessage to our JMS wishlist and let the implementor deal with encodings

Second, I prefer to use TextMessage even if it is dangerous and I manually keep in sync the "encoding" attribute of the XML message with the CCSID of my message asking everybody (developers & admins) to be very careful about MQ charset conversions that must always be associated with an update of the "encoding" attribute of the xml message.

To force the synchronization of the ccsid with the "encoding" attribute, I use the com.ibm.mq.jms.JMSC.CHARSET_PROPERTY JMS property.

Here is a pattern to keep XML "encoding" attribute and CCSID in sync :
Code:

javax.xml.transform.Source xmlSource = ...; // the XML Source ; e.g. StreamSource, JaxbSource, etc
String encoding = ...; // e.g. UTF-8, ISO-8859-1, etc
int ccsid = ...; // ccsid associated with encoding ; e.g. 1208, 819, etc

// SERIALIZE XML WITH THE GIVEN ENCODING
Transformer identityTransformer = TransformerFactory.newInstance().newTransformer();
identityTransformer.setOutputProperty(OutputKeys.ENCODING, encoding);
ByteArrayOutputStream out = new ByteArrayOutputStream();
identityTransformer.transform(xmlSource, new StreamResult(out));
String serializedXml = out.toString(encoding);

// CREATE XML MESSAGE WITH ENCODING AND CCSID IN SYNC
Message xmlMessage = session.createTextMessage(serializedXml);
xmlMessage.setStringProperty(JMSC.CHARSET_PROPERTY, String.valueOf(ccsid));

// SEND MESSAGE
MessageProducer messageProducer = session.createProducer(queue);
messageProducer.send(xmlMessage);


Detailed sample available here (see testSendXmlMessageIso88591() and testSendXmlMessageUtf8() ):
http://xebia-france.googlecode.com/svn/trunk/messaging/messaging-demo/src/main/java/fr/xebia/jms/mq/WebsphereMqTest.java

Note that we developed an IbmCharsetUtils class to convert ccsid to java charsets.

Hope this help,

Cyrille
_________________
Cyrille Le Clerc
cyrille@cyrilleleclerc.com
cleclerc@xebia.fr
http://blog.xebia.fr


Last edited by Cyrille Le Clerc on Sun Nov 11, 2007 9:18 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Cyrille Le Clerc
PostPosted: Tue Nov 06, 2007 10:28 am    Post subject: JMS Message types used by JMS transports of SOAP libraries Reply with quote

Novice

Joined: 23 May 2007
Posts: 12
Location: France

Hello,

Here is a short review of the JMS Message types used by leading Java JAXWS (ie SOAP) implementations for their JMS Transport :

* JAXWS-RI (aka JAXWS Reference Implementation) only supports BytesMessage. See com.sun.xml.ws.transport.jms.client.JMSClientTransport

* Apache CXF (merge of XFire and IONA Celtix) can use TextMessage (default type), BytesMessage or ObjectMessage (to transport a serialized bytes array). See org.apache.cxf.transport.jms.JMSTransportBase

* Apache Axis2 can use TextMessage (default type) or BytesMessage. See org.apache.axis2.transport.jms.JMSSender


At the end of the day,

* Every modern Java SOAP implementation support BytesMessage.

* TextMessage is the default for Axis2 and CXF but is not supported by JAXWS-RI.

* JAXWS-RI, the reference implementation, is 'slightly' paradoxical to not support TextMessage when the JMS javadoc talks about TextMessage to handle XML .

* I always have the same wish for JMS 2 : JCP, please add XmlMessage.

Hope this helps even if the panorama doesn't give a clear answer,

Cyrille
_________________
Cyrille Le Clerc
cyrille@cyrilleleclerc.com
cleclerc@xebia.fr
http://blog.xebia.fr


Last edited by Cyrille Le Clerc on Sun Nov 11, 2007 9:19 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
fjb_saper
PostPosted: Tue Nov 06, 2007 3:24 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

I completely understand you.
However you are limiting the message to specific implementations of SOAP/XML that always expect the message to be in UTF-8 and as such it matters little if TextMessage or BytesMessage.

Now look at a cobol implementation where the codeset might be 37 or 500 and need a translation... Which layer is going to make this translation???

For us techies we will reply MQ of Course, provided we got a text message from the sender. We will then know how to transform the message from ccsid 1208 to ccsid 500 and vice / versa...

Enjoy
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
Cyrille Le Clerc
PostPosted: Wed Nov 07, 2007 10:20 am    Post subject: Reply with quote

Novice

Joined: 23 May 2007
Posts: 12
Location: France

Hello,

I did a small shortcut on my apporach :

My preferred solution to send XML messages over JMS is to drive the XML encoding from the Queue's CCSID : the MQ admins specify specify the CCSID [1] and the java code forces the XML encoding according to this given ccsid (that we discover via (MQQueue) queue).getCCSID()) [2]. And I prefer TextMessage to BytesMessage to be friendly with apps that feel uncomfortable with bytes-to-char translations.

If this solution does not work, I like the idea of having as many "good xml&mq citizens" applications as possible a to use an ESB/EAI approach to adapt the messages for the applications that have xml|mq difficulties. Hopefully, these applications that have difficulties will evolve one day and become good citizens

Does this approach make sense for the translation use case you gave ?

For SOAP, I feel it really worth using an on-the-shelf SOAP library that deals with the marshalling/unmarshalling and encoding stuff and this library would, I guess, prefer UTF-8 that is the default encoding for XML. However, I don't know if there are such kind of soap libraries for cobol like languages. Forgive me, I am mostly a Java guy
In fact, I see more SOAP as a black box protocol rather than plain XML.
I feel the SOAP libraries should deal with transport issues and their underlying encoding. Extending Axis2, CXF or JAXWS-RI to specify the xml encoding seems pretty complex to develop and would be expensive to maintain.

Cyrille

[1] The MQAdmin can specify the ccsid via the QueueManager config, the JMS websphere config, etc.

[2] I use a IbmCharsetUtils.java util class to find the encoding associated with the ccsid.


Code:

// Sample that gets the CCSID from the MQQueue config and force the xml encoding to fit this ccsid

javax.xml.transform.Source xmlSource = ...; // the XML Source ; e.g. StreamSource, JaxbSource, etc
int ccsid = ((MQQueue) queue).getCCSID(); // e.g. 1208, 819, 307 etc
String encoding = IbmCharsetUtils.getCharsetName(ccsid); // e.g. UTF-8, ISO-8859-1, cs-ebcdic-cp-us, etc

// SERIALIZE XML WITH THE GIVEN ENCODING
Transformer identityTransformer = TransformerFactory.newInstance().newTransformer();
identityTransformer.setOutputProperty(OutputKeys.ENCODING, encoding);
ByteArrayOutputStream out = new ByteArrayOutputStream();
identityTransformer.transform(xmlSource, new StreamResult(out));
String serializedXml = out.toString(encoding);

// CREATE XML MESSAGE WITH ENCODING AND CCSID IN SYNC
Message xmlMessage = session.createTextMessage(serializedXml);
xmlMessage.setStringProperty(JMSC.CHARSET_PROPERTY, String.valueOf(ccsid));

// SEND MESSAGE
MessageProducer messageProducer = session.createProducer(queue);
messageProducer.send(xmlMessage);

_________________
Cyrille Le Clerc
cyrille@cyrilleleclerc.com
cleclerc@xebia.fr
http://blog.xebia.fr


Last edited by Cyrille Le Clerc on Sun Nov 11, 2007 9:22 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
JLRowe
PostPosted: Thu Nov 08, 2007 3:11 am    Post subject: Reply with quote

Yatiri

Joined: 25 May 2002
Posts: 664
Location: South East London

I have worked with the SonicMQ product in the past, and indeed it has an XMLTextMessage in its api that extends javax.jms.TextMessage. A very sensible extension.
Back to top
View user's profile Send private message Send e-mail
Cyrille Le Clerc
PostPosted: Thu Nov 08, 2007 10:01 am    Post subject: Reply with quote

Novice

Joined: 23 May 2007
Posts: 12
Location: France

Sonic MQ's XMLMessage is a nice direction to ease XML usage with JMS and Sonic Software should have a chair at the JMS JSR-914's expert group .

However, I regret they still associate XML with text (ie encoded chars) rather than handling pure XML message (i.e. a javax.xml.transform.Source) ; this would let let the JMS implementation decide how to serialize this XML (with possibility to change it by apis) [1].

My wish would be an extension of javax.jms.Message that handle a javax.xml.transform.Source and offer serialization properties similar to the javax.xml.transform.OutputKeys we have on the javax.xml.transform.Transformer

It could look like this XmlMessage.java :
Code:

/**
 * JMS {@link Message} with support for XML {@link Source}.
 */
public interface XmlMessage extends javax.jms.Message {

    /**
     * Sets the XML {@link Source} containing this message's data.
     *
     * @throws JMSException
     *             If the JMS provider fails to set the xml source due to some internal error.
     * @exception MessageNotWriteableException
     *                If the message is in read-only mode.
     */
    void setSource(javax.xml.transform.Source xmlSource) throws JMSException;

    /**
     * Gets the {@link Source} containing this message's data. The default value is
     * <code>null</code>.
     *
     * @return The <code>source</code> containing the message's data
     *
     * @exception JMSException
     *                If the JMS provider fails to get the xml source due to some internal error.
     */
    javax.xml.transform.Source getSource() throws JMSException;

    /**
     * Set an output property that will be in effect for the {@link Source} serialization.
     *
     * Serialization occurs during the {@link MessageProducer#send(Message)} invocation.
     *
     * Typical usage would be to define an encoding with OutputKeys.ENCODING property.
     *
     * @see <a href="http://www.w3.org/TR/xslt#output">XSL Transformations (XSLT) Version 1.0</a>
     * @see javax.xml.transform.OutputKeys
     * @see javax.xml.transform.Transformer#setOutputProperty(String, String)
     */
    void setOutputProperty(String name, String value) throws IllegalArgumentException;

    /**
     * ...
     * @see javax.xml.transform.Transformer#getOutputProperties()
     */
    Properties getOutputProperties();

    /**
     * ...
     * @see javax.xml.transform.Transformer#getOutputProperty(String)
     */
    String getOutputProperty(String name) throws IllegalArgumentException;

    /**
     * ...
     * @see javax.xml.transform.Transformer#setOutputProperties(Properties)
     */
    void setOutputProperties(Properties oformat);

}


It is just an humble wish and I hope the next JMS specification will do something for us

Cyrille


[1] Sources : Soniq MQ 7.5 Application Programming Guide and Soniq MQ 5.0 javadoc. Unfortunately, I did not find SoniqMQ 7.5 javadoc on the web but 5.0 javadoc seems to be consistent the the programming guide.
_________________
Cyrille Le Clerc
cyrille@cyrilleleclerc.com
cleclerc@xebia.fr
http://blog.xebia.fr
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Cyrille Le Clerc
PostPosted: Sun Nov 11, 2007 9:13 am    Post subject: Ongoing spec : SOAP over Java Message Service 1.0 RC1 Reply with quote

Novice

Joined: 23 May 2007
Posts: 12
Location: France

I just found this SOAP over Java Message Service 1.0 RC1 ongoing specification.

This specification has been initiated by BEA, IBM, Sonic and Tibco through an informal note written in Oct 2006 and announced in Jan 2007 on Axis Dev mailing list. Unfortunately, I couldn't find any public activity on this spec since the 01/2007 announcement.

It is interesting to note that this specification only supports JMS BytesMessage to transport SOAP messages.

However, we must remember that plain old XML and SOAP messages do NOT handle binary data in the same way : plain old XML messages use xsd:base64Binary or xsd:hexBinary types to hold the binary data in the XML tree when SOAP use performances optimized mechanisms like SOAP Message Transmission Optimization Mechanism (MTOM).

As a conclusion, we can expect that BytesMessage will be the most widely used JMS message type to transport SOAP messages even if this type is less friendly than TextMessage for programming languages/platforms that handle XML messages as text.
But this does not mean that BytesMessage is the smartest JMS message type for plain old XML documents. IMHO, TextMessage is very compelling to be friendly for programming languages / platforms that have difficulties to handle byte-to-char transformations.

Hope this help,

Cyrille

Extract from SOAP over Java Message Service 1.0 RC1 :
Quote:

...
2.4 The JMS Message Body

The contents of the JMS Message body MUST be the SOAP payload as a JMS BytesMessage. ... . The encoding will depend on whether the payload is simply a SOAP Envelope or whether there are any attachments, and the JMS "Content-type" header (sec 3.3) will reflect this appropriately.

In the case of a message without any attachments, the JMS Message Body will contain the properly encoded bytes of the XML SOAP message, and nothing else. In this case the Content-type will be "text/xml" (for SOAP 1.1) or "application/soap+xml" (for SOAP 1.2).

In the case that there are attachments, the JMS Message Body will contain a multipart MIME message. The first thing encountered in byte stream MUST be the MIME boundary for the start of the first part - what MIME Part One [RFC 2045] section 2.5 calls a "Body Part". The message will be encoded using SOAP Messages with Attachments [SwA] or XOP [SOAP11-MTOM] [SOAP12-MTOM], in either case with a Content-type of "multipart/related".
...

_________________
Cyrille Le Clerc
cyrille@cyrilleleclerc.com
cleclerc@xebia.fr
http://blog.xebia.fr
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
fjb_saper
PostPosted: Sun Nov 11, 2007 3:37 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

It makes sense that with the attachments the only possible message is a bytes message as it reduces drastically the size of the message (Otherwise any bytes array would need to be represented by its hex value in chars...)

So the bytes message does make sense. Keep in mind however that it expects the sending and receiving system's soap implementation to have the necessary CCSID converters that you get for free with a Text message.

Enjoy
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
zpat
PostPosted: Mon Nov 12, 2007 1:42 am    Post subject: Reply with quote

Jedi Council

Joined: 19 May 2001
Posts: 5849
Location: UK

We send XML as format MQSTR and use BASE64 to encode any binary attachments. This allows messages to be processed by any platform using MQGET with CONVERT. This preserves MQ's platform independence and allows loose coupling of applications.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » IBM MQ Java / JMS » XML in JMSTextMessage or JMSBytesMessage
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.