When large object messages or bytes messages are sent, the cost in memory and processor use of serializing, deserializing, and copying the message payload can be significant. If you enable the pass message payload by reference properties on a connection factory or activation specification, you tell the default messaging provider to override the JMS 1.1 specification and potentially reduce or bypass this data copying.
Background
The
JMS 1.1 specification states
that object messages are passed by value. This means that a JMS provider
such as the default messaging provider in WebSphere® Application Server has to take a copy of the
object in ObjectMessage at the time the object is
set into the message payload, in case the client application modifies
the object after setting it. In practice this means serializing it,
as there is no other entirely safe way to take a copy. The specification
also states that when a consumer application gets the data from the
message, the JMS provider must create and return a copy of that data.
If
you enable the "pass message payload by reference" properties,
you might get memory and performance improvements for JMS messaging.
CAUTION:
- The parts of the JMS specification that are
bypassed by these
properties are defined to ensure message data integrity.
- Any
of your JMS applications that use these properties must strictly
follow the rules that are described in detail later in this section,
or you risk losing data integrity.
- You should read and understand
this entire topic before enabling
these properties.
To pass the message payload by reference, you
set the following properties on connection factories and activation
specifications:
- producerDoesNotModifyPayloadAfterSet (for
connection factories) or forwarderDoesNotModifyPayloadAfterSet (for
activation specifications)
- When this property is enabled, object or bytes messages produced
by the connection factory or forwarded through the activation specification
are not copied when set into the message and are only serialized when
absolutely necessary. Applications sending such messages must not
modify the data after it has been set into the message.
- consumerDoesNotModifyPayloadAfterGet
- When this property is enabled, object messages received through
the connection factory or activation specification are only serialized
when absolutely necessary. The data obtained from those messages must
not be modified by applications.
Potential
benefits of passing the message payload
by reference
The following table shows the conditions under
which you might get performance benefits by enabling the
"pass message
payload by reference" properties. This table makes the following
assumptions:
- Your JMS applications conform to the rules described
in the next
section of this topic.
- Your message producer and consumer
applications run in the same
JVM (server), along with the messaging engine that hosts the destination
used by these applications.
Note: - If your applications
run in different servers, or on the z/OS® platform
(where WebSphere Application Server runs in multiple
JVMs), then object messages are serialized and no performance benefits
are gained for these messages. Bytes message benefits might still
be gained.
- There are many internal runtime conditions that
can cause your
messages to be serialized, so even if your configuration meets all
the conditions described in this topic you might gain little or no
performance benefit from enabling the "pass message payload by reference" properties.
Table 1. How configuration
and runtime factors determine what data is copied, when it is copied,
and the potential performance benefit.. The first column
lists the degree of potential performance benefits. The second column
includes the configuration and runtime events of the potential benefits.
The third column provides information such as what data is copied
and when the data is copied based on the configuration and runtime
events of the potential benefits.Degree of potential
performance benefit |
Configuration and
runtime events |
When the data is copied |
No potential benefit |
The "pass message payload by reference" properties
are not enabled (default behavior).
|
Object
message data is copied as soon as
it is set into the message and when it is retrieved from the message.
Bytes
message data is copied as soon as it is set into the message and when
it is retrieved from the message.
|
Some potential benefit |
The "pass
message payload by reference" properties
are enabled, and either or both of the following conditions are true: - The send or receive message is transacted.
- The consumer
is not available when the message is produced.
|
Object message data
is only copied when necessary.
Bytes message data is only copied
when necessary.
|
Maximum
potential benefit |
The "pass message
payload by reference" properties
are enabled, and both of the following conditions are true: - Neither
the send nor the receive message is transacted.
- The consumer
is waiting for the message when it is produced (for
example if the consumer is a message-driven bean).
|
Object message data
might never be copied.
Bytes message data is only copied when
necessary.
|
Rules
that your JMS applications must obey
The
parts of the JMS specification that are bypassed by the "pass message
payload by reference" properties are defined to ensure message
data integrity. If your JMS applications obey the rules given in the
following table, then you can safely enable the "pass message payload
by reference" properties on the connection factories and activation
specifications that the applications use.
If you enable the "pass
message payload by reference" properties for JMS applications that
do not follow these rules, then the applications might receive exceptions
or, more importantly, the integrity of the message data might be compromised.
Table 2. Rules that your JMS applications must
obey, by application type. The first column lists the
JMS application types. The second column provides the rules that the
JMS application must follow.Application type |
Rules |
JMS producer application |
A JMS producer application that sends object
messages must not alter the object after it is set into the payload
of the message.
A JMS producer application that sends bytes
messages: - must write data into the message with a single call
to writeBytes(byte[]).
- must not alter the
byte array after it is written into the message.
|
JMS consumer application |
A JMS consumer application that receives
object messages must not alter the payload it gets from the message.
|
JMS forwarder application Note: A JMS forwarder application receives a message (through a connection factory, or if it is a message-driven bean through an activation specification), then sends the message object on to another destination.
|
A JMS forwarder application that replaces
the payload of the received message with a new payload: - (for
object messages) must not alter the object after it is set
into the payload of the message.
- (for bytes messages):
- must
write data into the message with a single call to writeBytes(byte[]).
- must not alter the byte array after it is written into the message.
|
Ensuring that your object messages can be serialized
Under
normal JMS messaging conditions (that is, when the "pass message
payload by reference" properties are not enabled), the data in
an object message is serialized as soon as the object is passed to
the messaging system, for example on set or send.
If the message payload cannot be serialized, then an exception message
is immediately returned to the client application.
When the "pass
message payload by reference" properties are enabled, the message
payload is accepted from the client application without attempting
to serialize it. If the system later discovers that the data cannot
be serialized, the system can no longer inform the client application
that sent the message - and because the data is not serializable,
the system cannot persist or transmit the complete message. The message
and its properties are stored, but the user data inside the message
(the payload) cannot be stored and is discarded. If there are serialization
problems when the system tries to convert an object message into a
data graph for a mediation, the message payload is discarded and the
mediation receives a message with the data value set to null.
If
your data cannot be serialized, then it is lost. Therefore you should
first test your configuration without enabling the "pass message
payload by reference" properties, to check that all data sent into
the system is serializable.
When the system discovers that
an object message cannot be serialized, it writes the following error
message (JMS_IBM_ExceptionMessage) to the
SystemOut.log file,
where
"{0}" is replaced by the class name of the failing object:
Note: This topic references one or more of the application
server log files. As a recommended alternative, you can configure
the server to use the High Performance Extensible Logging (HPEL) log
and trace infrastructure instead of using SystemOut.log , SystemErr.log, trace.log, and activity.log files on distributed and IBM® i systems. You can also use
HPEL in conjunction with your native z/OS logging facilities. If you are using HPEL, you can access
all of your log and trace information using the LogViewer command-line
tool from your server profile bin directory. See the information
about using HPEL to troubleshoot applications for more information
on using HPEL.
- CWSIK0200E: An object of class "{0}" has been set
into the
message payload but it cannot be serialized.
- Explanation:
An object message sent with the producerDoesNotModifyPayloadAfterSet flag
enabled on its connection factory was sent with a payload that was
not serializable by the system. This message data has been lost.
- Action: Disable the producerDoesNotModifyPayloadAfterSet on
the connection factory. Without the flag enabled, the JMS application
that sets the object into the message will receive any serialization
exception immediately.
The following exception
properties
are used to indicate that a data object cannot be serialized and has
been discarded. JMS applications can find out what has happened from
the
JMS_IBM_Exception properties. Mediations can
find out what has happened from the
JMS_IBM_Exception and
SI_Exception properties.
- JMS_IBM_ExceptionReason
- SIRCConstants.SIRC0200_OBJECT_FAILED_TO_SERIALIZE
- JMS_IBM_ExceptionTimestamp
- The time
at which the object failed to serialize, in System.currentTimeMillis() form.
- JMS_IBM_ExceptionMessage
- Message CWSIK0200E,
as previously described.
- SI_ExceptionReason
- SIRC0200_OBJECT_FAILED_TO_SERIALIZE
- SI_ExceptionTimestamp
- The time at which the object failed to serialize, in System.currentTimeMillis() form.
- SI_ExceptionInserts
- A string array
containing one entry. The entry contains the class
name of the object.
Note: The most likely explanation
as to why your
data objects cannot be serialized is that you have written your own writeObject() or writeExternal() methods
and have not fully tested every option (for example NullPointer exceptions,
or ArrayIndexOutOfBounds exceptions).