This page describes an older version of the product. The latest stable version is 14.5.

JMS-Space Interoperability

JMS-space interoperability allows JMS applications to communicate with non-JMS applications using the space, without having to know or deal with the space API.

XAP introduced the ability for JMS applications to write messages to the space by implementing them as Externalizable MetaDataEntries, thus allowing non-JMS applications (usually space API applications) to read these MetaDataEntries using a template.

Furthermore, since XAP, an application using the space API can write JMS messages of any type to the space, using the space API (without knowing JMS). Therefore, it is possible to handle JMS messages the same way as any other Entry type.

With XAP, it is possible for the JMS application to control and decide exactly which type of object is written to the space, as long as the written object is valid for the receiving/reading application. This is done using the new MessageConverter feature. A common use-case is writing a JMS message to the space, where the message is “stripped” on the space side, leaving only the message body, usually a POJO. The space application can then read the POJO using a template that includes only the POJO type.

To summarize, the table below shows which operations are supported, allowing interoperability between the JMS and space API.

Operation

JMS Application

Space Application

Write JMS messages to space

Write Entries to space

Write POJOs (or objects of any type) to space

Read JMS messages from space

Read Entries/POJOs from space

Note

As shown above, a JMS application cannot read POJOs/Entries from the space, unless they are part of a JMS message.

The following sections will show you how to use the MessageConverter to write objects to the space using the JMS API; and how to write JMS messages and read/take those messages using the space API.

Writing POJOs/Entries to Space using JMS API – MessageConverter

This feature allows clients to define the outcome of JMS writes. By implementing a MessageConverter, you can convert JMS messages to a POJO before they are written to the space. The result of using a converter is that what is written to the space is not necessarily the JMS message (with all the headers, properties etc.), but the result of the message conversion.

A basic use-case of this feature might be writing POJOs to the space using standard JMS API, and not the space API.

A simple implementation of this conversion is the ObjectMessage2ObjectConverter class. When the MessageConverter is invoked by passing an ObjectMessage to its toObject method, it returns the contained POJO (message’s body). When using the MessageConverter to send ObjectMessages, what is actually written to the space is only the JMS message body, which contains the POJO. The ObjectMessage wrapper is not written.

You can create a custom implementation of the MessageConverter. The returned object can be an Entry, an object, an array of Entries, or an array of objects. The returned object can be the same JMS message passed as an argument, or a different one. Generally, the possibility of what can be returned from the conversion method are endless, however, the returned objects should be Entries or POJOs, valid for working with the space.

IMessageConverter Interface

This interface defines an API for message conversion:

interface IMessageConverter {
Object toObject(javax.jms.Message m);
}

Implement the IMessageConverter interface to return the object required to be written to the space.

Following is the implementation code of ObjectMessage2ObjectConverter:

In this case, the MessageConverter is used even if another MessageConverter is set in the ConnectionFactory.

MessageConverter Resolution

In case a MessageConverter is set for a ConnectionFactory, and another MessageConverter is set in a message, GigaSpaces resolves this in the following order:

The MessageConverter is set in the message’s JMS_GSMessageConverter property.

The MessageConverter is set in the ConnectionFactory.

Note

If no MessageConverter is set, the JMS message is written as-is.

Only one MessageConverter is used each time.

Considerations

Message conversion is performed before the space write action. When using transactions, the messages are written to the space only after the transaction is committed. Therefore, changing a MessageConverter during a transaction affects all conversions performed by this converter in this specific transaction.
For example, a converter that returns an object of type A – during a transaction, a few messages are sent, and then the properties of the converter are changed to return an object of type B. When committing the transaction, all messages using this converter are converted to objects of type B.

Setting the JMS_GSMessageConverter property to null is the same as disabling the MessageConverter set in the ConnectionFactory.
No conversion is performed and the JMS messages are written as-is.

TextMessage compression is still performed if the returned object is a TextMessage.

Setting the JMS_GSMessageConverter property with an object that doesn’t implement IMessageConverter throws a MessageFormatException.

After calling MessageProducer.send(), the message instance behaves as if no conversion occurred. The JMS_GSMessageConverter property in the returned object is unset.

A destination has to be created, even if it is not used in the converted object.

3. Write Message to Space

The SpaceWriter example that resides in <XAP Root>\examples\Basic\helloJMS uses this technique to write JMS messages to the space.

Reading/Taking JMS Messages

Like with any Entry/POJO type, to receive a JMS message from the space you need to create a template. The template is matched with the objects in the space, and matching objects are retrieved. All public members of the message class participate in the match process, including the properties map. Therefore, if you don’t know the exact content of a message properties map, it is better to set it to null in the JMS message template.

To create a generic template for all kinds of JMS messages, create an instance of GSMessageImpl as follows:

GSMessageImpl genericMessageTemplate = new GSMessageImpl();

Using the default constructors creates a null template of the JMS message. This means that the properties map is also null. If you do not use the default constructor, you should set the properties map to null by invoking:

jsmMessageTemplate.setProperties(null);

2. Read/Take from the Space

You can use the template to read or take messages from the space. The following example takes a text message from the space: