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:
The Progress 4GL–JMS message life cycle for receiving a message has these general steps:
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:
- In Java, the name of the method determines the data type to be converted to. For example, readString() extracts a value such as an Integer data type from a StreamMessage and converts it to a String data type.
- In the 4GL, the equivalent function is readChar() to convert an Integer value to a 4GL CHARACTER data type.
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–3 maps the available conversions from JMS data types to 4GL data types for data extraction.
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:
This example specifies 40MB for the memory heap, 8MB for the stack, and 8MB for the stack object memory:
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:
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |