IBM Support

IT31238: MQ classes for Java application cannot get NameValueData from RFH2 when using CCSID 1200 with little endian encoding

Subscribe to this APAR

By subscribing, you receive periodic emails alerting you to the status of the APAR, along with a link to the fix after it becomes available. You can track this item individually or track all items by product.

Notify me when this APAR changes.

Notify me when an APAR for this component changes.

 

APAR status

  • Closed as program error.

Error description

  • A MQ classes for Java application consumes a message from a
    queue, where the message contains an RFH2 header.
    
    The MQMD declares that the RFH2 is formatted using:
    
      Encoding = 0x222
    
    to indicate that the numerical data fields in the RFH2 are
    encoded using a little-endian encoding scheme.
    
    The NameValueCCSID field declares that the NameValueData is
    encoded using the character encoding CCSID 1200 (UTF-16).
    
    The application extracts the MQRFH2 header from the received
    message, and then calls the method:
    
         com.ibm.mq.headers.MQRFH2.getFolderStrings();
    
     to return a String array of the NameValueData entries in the
    RFH2.  However an empty String array is returned by the MQ
    classes for Java.
    
    
    It is noted that if the RFH2 encoding is set as:
    
      Encoding = 0x111
    
    and the RFH2 is structured to match this encoding, then the call
    to "getFolderStrings()" returns a String array of the elements
    in the MQRFH2 header.  The issue is also not seen if the
    NameValueCCSID field is set to 1208, with appropriately
    character encoded NameValueData entries.
    

Local fix

  • Update the application which creates the message to use a
    big-endian encoded RFH2, or do not use CCSID 1200 for the
    NameValueCCSID field of the RFH2.
    

Problem summary

  • ****************************************************************
    USERS AFFECTED:
    Users of the IBM MQ classes for Java who are consuming messages
    from a queue and inspecting the RFH2 header, where:
    
    (a) The RFH2 header is declared to be encoded in little endian
    (eg. encoding = 0x222).
    (b) The NameValueCCSID field in the RFH2 declares the
    NameValueData to be character encoded in CCSID 1200.
    
    
    Platforms affected:
    MultiPlatform
    
    ****************************************************************
    PROBLEM DESCRIPTION:
    An RFH2 header might be structured as follows:
    
    Fixed section:
    52 46 48 20 --> StrucId (MQCHAR4):     'RFH '
    00 00 00 02 --> Version (MQLONG):      '2'
    00 00 00 60 --> Struc Length (MQLONG): '96'
    00 00 01 11 --> Encoding (MQLONG):     '0x111'
    00 00 03 33 --> CCSID:                 '819'
    4D 51 53 54 52 20 20 20 --> Format (MQCHAR8) 'MQSTR   '
    00 00 00 00 --> RFH Flags (MQLONG)     '0'
    00 00 04 b0 --> NameValueCCSID (MQLONG) '1200'
    
    Variable section:
    00 00 00 18 --> NameValueLength (MQLONG) '24'
    003c 0041 003e 0061 0070 0070
    006c 0065 003c 002f 0041 003e --> NameValueData '<A>apple</A>'
    00 00 00 1c --> NameValueLength (MQLONG) '28'
    003c 0042 003e 0062 0061 006e
    0061 006e 0061 0073 003c 002f
    0042 003e                     --> NameValueData '<B>bananas</B>'
    
    The numerical fields in this structure are big-endian encoded,
    as is the UTF-16 character encoding in the variable section.
    That is to say if the previous header to the RFH2 in the MQ
    message was the MQMD, then the encoding value would be set as
    big-endian:
    
      MQMD.encoding = 0x111
    
    If an MQ classes for Java application consumed this message, and
    extracted the NameValueData strings from the RFH2 using the MQ
    classes for Java methods:
    
      MQHeaderList mqHeaderList = new MQHeaderList(receivedMessage,
    true);
      int rfh2Index = mqHeaderList.indexOf("MQRFH2");
      MQRFH2 mqrfh2 = (MQRFH2)mqHeaderList.get(rfh2Index);
      String[] folderStrings = mqrfh2.getFolderStrings();
    
    then the String array "folderStrings" would contain an array of
    two String objects, those being:
    
      (1)  "<A>apple</A>"
      (2) "<B>bananas</B>"
    
    
    However, if the RFH2 was numerically encoded in a little-endian
    format, the data would resemble:
    
    Fixed part:
    52 46 48 20 --> StrucId (MQCHAR4):     'RFH '
    02 00 00 00 --> Version (MQLONG):      '2'
    60 00 00 00 --> Struc Length (MQLONG): '96'
    11 01 00 00 --> Encoding (MQLONG):     '0x111'
    33 03 00 00 --> CCSID:                 '819'
    4D 51 53 54 52 20 20 20 --> Format (MQCHAR8) 'MQSTR   '
    00 00 00 00 --> RFH Flags (MQLONG)     '0'
    b0 04 00 00 --> NameValueCCSID (MQLONG) '1200'
    
    Variable part:
    a8 00 00 00 --> NameValueLength (MQLONG) '24'
    3c00 4100 3e00 6100 7000 7000
    6c00 6500 3c00 2f00 4100 3e00 --> NameValueData '<A>apple</A>'
    1c 00 00 00 --> NameValueLength (MQLONG) '28'
    3c00 4200 3e00 6200 6100 6e00
    6100 6e00 6100 7300 3c00 2f00
    4200 3e00                    --> NameValueData '<B>bananas</B>'
    
    
    then the String array would be empty.
    
    If trace was examined of the application inspecting the RFH2 in
    this way, the following exception would be observed when the
    message was being consumed from the queue:
    
    c.i.mq.headers.MQRFH2$MQRFH2Element   ----+-  X
    <init>(String)<catchIndex 1>
    Content is not allowed in prolog.
    [org.xml.sax.SAXParseException] at:
    
    org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseExcepti
    on
      org.apache.xerces.util.ErrorHandlerWrapper.fatalError
      org.apache.xerces.impl.XMLErrorReporter.reportError
      org.apache.xerces.impl.XMLErrorReporter.reportError
      org.apache.xerces.impl.XMLScanner.reportFatalError
    
    org.apache.xerces.impl.XMLDocumentScannerImpl$PrologDispatcher.d
    ispatch
    
    org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocume
    nt
      org.apache.xerces.parsers.XML11Configuration.parse
      org.apache.xerces.parsers.XML11Configuration.parse
      org.apache.xerces.parsers.XMLParser.parse
      org.apache.xerces.parsers.AbstractSAXParser.parse
      org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse
      org.apache.xerces.jaxp.SAXParserImpl.parse
      com.ibm.mq.headers.MQRFH2FolderParser.parseFolder
      com.ibm.mq.headers.MQRFH2$MQRFH2Element.<init>
      com.ibm.mq.headers.MQRFH2.getExpandFolders
      com.ibm.mq.headers.MQRFH2.getFolders
      com.ibm.mq.MQMessage.parsePropertiesRfh2
      com.ibm.mq.MQMessage.readPropertiesRfh2
      com.ibm.mq.MQMessage.performProcessingAfterGet
      com.ibm.mq.MQDestination.getInt
      com.ibm.mq.MQDestination.get
      MyApplication.myMethod
    
    
    A point to note about the MQ character encoding of the CCSID
    1200/13488/17584 is documented in the Knowledge Center:
    
    https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.
    ibm.mq.dev.doc/q032000_.htm
    
    which reads:
    
    "NameValueCCSID (MQLONG)
    The coded character set identifier (CCSID) for the NameValueData
    character strings
    contained in this header. The NameValueData can be coded in a
    character set that
    differs from the other character strings that are contained in
    the header (StrucID
    and Format).
    
    If the NameValueCCSID is a 2 byte Unicode CCSID (1200, 13488, or
    17584), the byte
    order of the Unicode is the same as the byte ordering of the
    numeric fields in the
    MQRFH2. (For example, Version, StrucLength, and NameValueCCSID
    itself.)"
    
    
    That is to say, for these CCSID values the byte ordering of the
    NameValueData character data is determined by the numerical
    encoding of the RFH2 header.
    

Problem conclusion

  • The MQ classes for Java was not programmed to take the RFH2
    numerical encoding value into account when determining the
    byte-order of the NameValueData character data when it was
    declared to be character encoded in CCSID 1200, 13488, 17584.
    
    As a consequence it was unable to parse the fields correctly to
    locate the XML-like NameValueData structured fields.
    
    
    The MQ classes for Java has been updated to take the RFH2
    numerical encoding value into account to determine the
    byte-order of the character data when using these NameValueCCSID
    values.
    
    ---------------------------------------------------------------
    The fix is targeted for delivery in the following PTFs:
    
    Version    Maintenance Level
    v7.5       7.5.0.10
    v8.0       8.0.0.15
    v9.0 LTS   9.0.0.10
    v9.1 CD    TBC.
    v9.1 LTS   9.1.0.6
    
    The latest available maintenance can be obtained from
    'WebSphere MQ Recommended Fixes'
    http://www-1.ibm.com/support/docview.wss?rs=171&uid=swg27006037
    
    If the maintenance level is not yet available information on
    its planned availability can be found in 'WebSphere MQ
    Planned Maintenance Release Dates'
    http://www-1.ibm.com/support/docview.wss?rs=171&uid=swg27006309
    ---------------------------------------------------------------
    

Temporary fix

Comments

APAR Information

  • APAR number

    IT31238

  • Reported component name

    IBM MQ BASE M/P

  • Reported component ID

    5724H7261

  • Reported release

    900

  • Status

    CLOSED PER

  • PE

    NoPE

  • HIPER

    NoHIPER

  • Special Attention

    NoSpecatt / Xsystem

  • Submitted date

    2019-12-11

  • Closed date

    2020-03-11

  • Last modified date

    2020-03-11

  • APAR is sysrouted FROM one or more of the following:

  • APAR is sysrouted TO one or more of the following:

Fix information

  • Fixed component name

    IBM MQ BASE M/P

  • Fixed component ID

    5724H7261

Applicable component levels

[{"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Product":{"code":"SSYHRD","label":"IBM MQ"},"Component":"","ARM Category":[],"Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"9.0","Edition":"","Line of Business":{"code":"LOB36","label":"IBM Automation"}}]

Document Information

Modified date:
27 March 2020