Progress
External Program
Interfaces


Messages

The 4GL object model for messages is very similar to the Java object model. Each supported JMS message type has a 4GL counterpart, and, with some exceptions, each JMS message method is supported by a 4GL method with the same name. In particular, the getJMS... and setJMS... header methods are fully supported (See the Java Message Service specification and the SonicMQ Programming Guide for details.)

A Progress 4GL–JMS message can have either of two life cycles—one for creating a message and one for receiving a message.

The Progress 4GL–JMS message life cycle for creating a message has these general steps:

  1. Create a message by running create...Message (for example, createXMLMessage) in the Session object.
  2. Populate a message by running set... and write... for header and data information.
  3. Send the message to a destination.
  4. Run deleteMessage to delete the message.

The Progress 4GL–JMS message life cycle for receiving a message has these general steps:

  1. Receive a message in a consumer object
  2. Run get... and read... to extract header information and body data.
  3. Run deleteMessage to delete the message.
Data Storage and Extraction Methods

An important difference between the 4GL model and the Java model is the difference in the names of the methods that extract data from a message:

When writing data to a message, an application uses the name of the data type to specify the Java data type in the message; the 4GL name is identical to the Java name. For example, Java uses the writeShort(short) method to write a number to a StreamMessage as short. The 4GL counterpart is the internal procedure, writeShort(value AS INTEGER).

Conversion between 4GL decimal values and Java double/float values follows the Java rules. (See the publications available at http://www.java.sun.com.)

Table 13–2 maps the 4GL data types to the JMS data types for data storage.

Table 13–2: Data Storage Table
4GL Data Type
JMS Data Type
LOGICAL
boolean
INTEGER
byte
INTEGER
short
INTEGER
int
DECIMAL
long
DECIMAL
float
DECIMAL
double
CHARACTER
String
A single CHARACTER
char
RAW
bytes array
MEMPTR
bytes array (only with BytesMessage)

Table 13–3 maps the available conversions from JMS data types to 4GL data types for data extraction.

Table 13–3: JMS and 4GL Data Types For Extracting Data
JMS Data Type
4GL Data Type
boolean
LOGICAL or CHARACTER
byte
INTEGER, DECIMAL, or CHARACTER
short
INTEGER, DECIMAL, or CHARACTER
int
INTEGER, DECIMAL, or CHARACTER
long
DECIMAL or CHARACTER
float
DECIMAL or CHARACTER
double
DECIMAL or CHARACTER
String
CHARACTER
char
CHARACTER
bytes array
RAW or MEMPTR (MEMPTR is available only with BytesMessage)

Message Handles

As in Java, a 4GL application obtains a handle to a message by creating it or receiving the message handle as an INPUT parameter of the message handler procedure. The 4GL application creates a message of a particular type by making a create...Message call (for example, createTextMessage) in the Session object. Messages are received by the message handler that was installed in a Message Consumer object. (For more information, see the "Message Consumer Object," "Subscribing To a Topic," and "Receiving Messages From a Queue" sections in this chapter.)

Message Typing

Unlike Java, 4GL Message objects are not typed. Therefore, the 4GL application must call the getMessageType function (returns CHAR) if it does not know what message type it expects to receive, so that it can make the correct function calls to extract the data.

Header Methods

All message types have the same header information and support the same methods, mostly for setting and getting header information. This follows the Java model in which all message types extend the basic Message interface. (For more information, see the "Message Objects" section in this chapter.)

Deleting Messages

Unlike Java, which uses garbage collection, with the 4GL–JMS API, messages that are not used must be explicitly deleted using the deleteMessage internal procedure (supported by all message types).

TextMessage

A TextMessage is a message type whose body contains text data. To send and receive a TextMessage over 32K, the 4GL–JMS API extends the JMS API with methods to concatenate text segments. As with Java–JMS, text data is extracted and stored in a message by the getText and setText methods for any TextMessage less than 32K.

To send and receive a TextMessage that exceeds the 32K limit, the 4GL–JMS API extends the JMS API with the appendText and getTextSegment methods. With multiple appendText calls, a 4GL client can create a TextMessage up to the limit of the JMS server. The JMS non-4GL client receives one TextMessage consisting of the concatenation of all the text segments.

To allow the 4GL client to receive messages larger then 32K, the server segments the received TextMessage into text segments of 8K (8192) or fewer characters. An application can then use multiple getTextSegment methods to retrieve all the segments. If getText is called, the 4GL–JMS API returns all the text. If the TextMessage is too large for the 4GL interpreter to handle, a run-time error occurs.

For example, if the message value is UNKNOWN, or “”, or a String of 5,000 characters, an application can use one getText call (or one getTextSegment call). If the message size is 16,400 characters, the first two getTextSegment calls return 8192 characters each, and the last getTextSegment call returns 16 characters. An application can use the getCharCount call to get the total number of characters in a message.

The endOfStream TextMessage function returns true when all of the segments are retrieved (the number of getTextSegment calls matches the number of segments). The setText call implicitly calls clearBody before setting the new text. The reset and getText calls transfer the message from write-only to read-only mode and position the message cursor before the first segment. (For more information, see the "Read-only and Write-only Modes" section in this chapter.)

NOTE: The 8K segment size is guaranteed. A 4GL application does not have to use the endOfStream function for messages smaller then 8K, since there is only one segment. For information about code-page conversions and text-size limits, see the "Internationalization Considerations" section in Using the SonicMQ Adapter."

XMLMessage

The 4GL–JMS API supports SonicMQ’s XMLMessage. As with SonicMQ, XMLMessage is an extension of a JMS TextMessage. XMLMessage supports the same methods as TextMessage.

XML messages can be used in conjunction with the 4GL XML parser:

It is important to consider the code page of XML messages. Theoretically, XML documents can be encoded using any code page. However, each XML parser supports some or all code pages, and XML parsers differ in the code-page conversions they can do. (A code page is table that maps each character on it to a unique numeric value.)

With the 4GL–JMS API, the conversion rules are straightforward. The text stored in an XML message by the 4GL application is expected to be encoded in the internal code page of the 4GL client (the –cpinternal startup parameter).

The 4GL–JMS implementation automatically converts the text to Unicode when a SonicMQ XML message is created. Unicode is an encoding format that provides a unique number for every character, no matter which platform, program, or language. The 4GL–JMS implementation also converts the Unicode text received in XML messages to the internal code page of the 4GL client when the text is extracted. For more information, see the "XML Code-page Encoding" section in this chapter.

StreamMessage

A StreamMessage is message whose body contains data that is written and read as a stream of basic data types; it is filled and read sequentially. There is a difference in the way a StreamMessage is read with the Java–JMS model and the 4GL–JMS model:

A separate call to retrieve the data type is not required in the Java–JMS model since the data type can be derived from the object type returned by the readObject Java method.

BytesMessage

A BytesMessage sends a stream of uninterpreted bytes. This message type allows passing data “as is” without any interpretation by the 4GL–JMS API or the JMS server. For example, a BytesMessage can pass an XML document encoded in a code page that does not match the 4GL client’s code page. (For more information, see the "XML Code-page Encoding" section in this chapter. For an example, see the "Publishing, Subscribing, and Receiving an XML Document In a BytesMessage" section in Using the SonicMQ Adapter.")

An application writes data to a BytesMessage using RAW or MEMPTR variables with writeBytesFromRaw or setMemptr and reads data with g readBytesToRaw or getMemptr. (For an example, see the "Publishing, Subscribing, and Receiving the Customer Table In a StreamMessage" section in Using the SonicMQ Adapter."

As with a TextMessage, the 4GL–JMS API accommodates messages larger than 32K by allowing multiple readBytesFromRaw and writeBytesToRaw calls. (For more information, see the "TextMessage" section in this chapter.)

MultipartMessage

A MultipartMessage can contain one or more of the following:

To create a multipart message, use the createMultipartMessage method. For a reference entry, see the createMultipartMessage section in "4GL–JMS API Reference." For an example, see the MultipartMessage section in this chapter.

Java Object Messages

Java Object messages are not supported by the 4GL–JMS API. If a Java Object message is received on behalf of a 4GL client, the client’s asynchronous error handler receives a TextMessage with the header of the Java Object message and a text body with the string, “ObjectMessage: Not Supported.” (For more information, see the "Error and Condition Handling" section in this chapter.)

Read-only and Write-only Modes

As in Java–JMS, the StreamMessage, TextMessage, XMLMessage, and BytesMessage are created in write-only mode. In write-only mode, an application can use only data-setting methods, not data-extraction methods. The reset call puts the cursor before the first item of the message and transfers it to read-only mode. Note that the publish, sendToQueue, and requestReply methods call reset implicitly. The message is received by the receiver in reset mode. The clearBody call transfers the message to write-only mode.

Note that read-only and write-only refer to the body of the message, not its header. Read-only and write-only modes do not apply to Header messages, since they lack a body.

Unlike in Java–JMS, a MapMessage in the 4GL–JMS implementation is always in read/write mode; there is no read-only or write-only mode for a MapMessage.

Reset has no effect when called in Map and Header messages.

clearBody and clearProperties

The clearBody and clearProperties methods are supported by all message types:

Message Size Limits

There is no limit to the 4GL message size. SonicMQ does not have a hard-coded maximum message size; the largest tested message is 1MB. The 4GL imposes a 32K limit on each item of a StreamMessage or a MapMessage. For more information about code-page conversions and text size limits, see the "Internationalization Considerations" section in Using the SonicMQ Adapter."

When using very large messages (above 1MB), you might need to modify the JVM’s memory limit values in the jvmArgs property of the SonicMQ Adapter broker (in the ubroker.properties file). For example, if the SonicMQ Adapter fails with an OutofMemory error in the log, you should modify:

–mx, –ss, and –oss 

This example specifies 40MB for the memory heap, 8MB for the stack, and 8MB for the stack object memory:

–mx40m –ss8m –oss8m 

Limit To the Number Of Messages

The value of the 4GL global variable, JMS–MAXIMUM–MESSAGES, determines the maximum number of Message objects in a 4GL session. An application must delete unused messages using the deleteMessage method of the Message object to avoid exceeding the JMS–MAXIMUM–MESSAGES value. The default value of JMS–MAXIMUM–MESSAGES is 50. An application can change the value of JMS–MAXIMUM–MESSAGES by declaring it in the 4GL application. For example, to change the value of JMS–MAXIMUM–MESSAGES from 50 to 100, the main 4GL procedure of the application must include the following definition:

DEFINE NEW GLOBAL SHARED VARIABLE JMS-MAXIMUM-MESSAGES AS INT INIT 100. 


Copyright © 2004 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095