Skip to content

Receiving messages from JMS

The JMS Connector retrieves JMS Message and maps each of them into Reactive Messaging Messages.

Example

Let’s imagine you have a jakarta.jms.ConnectionFactory bean exposed and connected to your JMS server. Don’t forget that it’s required to use the JMS connector.

Configure your application to receive JMS messages on the prices channel as follows:

mp.messaging.incoming.prices.connector=smallrye-jms

Note

You don’t need to set the destination. By default, it uses the channel name (prices). You can configure the destination attribute to override it.

Note

By default the connector uses a queue. You can configure it to use a topic by setting destination-type=topic.

Then, your application receives Message<Double>. You can consume the payload directly:

package jms.inbound;

import jakarta.enterprise.context.ApplicationScoped;

import org.eclipse.microprofile.reactive.messaging.Incoming;

@ApplicationScoped
public class JmsPriceConsumer {

    @Incoming("prices")
    public void consume(double price) {
        // process your price.
    }

}

Or, you can retrieve the Message<Double>:

package jms.inbound;

import java.util.concurrent.CompletionStage;

import jakarta.enterprise.context.ApplicationScoped;

import org.eclipse.microprofile.reactive.messaging.Incoming;
import org.eclipse.microprofile.reactive.messaging.Message;

@ApplicationScoped
public class JmsPriceMessageConsumer {

    @Incoming("prices")
    public CompletionStage<Void> consume(Message<Double> price) {
        // process your price.

        // Acknowledge the incoming message
        return price.ack();
    }

}

Deserialization

The content of the incoming JMS message is mapped to a Java object.

By default it extracts the JMS Message body as a java.lang.Object. This can be changed by setting, in the incoming JMS Message:

  1. The _classname property

  2. the JMSType

The value must be a fully qualified class name. The connector then load the associated class.

Note

The connector loads the associated Class using the TCCL and if not found, the classloader used to load the connector.

If the target type is a primitive type ort String, the resulting message contains the mapped payload.

If the target type is a class, the object is built using included JSON deserializer (JSON-B and Jackson provided OOB from the JMSType. If not, the default behavior is used (Java deserialization).

Inbound Metadata

Messages coming from JMS contains an instance of io.smallrye.reactive.messaging.jms.IncomingJmsMessageMetadata in the metadata.

1
2
3
4
5
6
Optional<IncomingJmsMessageMetadata> metadata = incoming.getMetadata(IncomingJmsMessageMetadata.class);
metadata.ifPresent(meta -> {
    long expiration = meta.getExpiration();
    Destination destination = meta.getDestination();
    String value = meta.getStringProperty("my-property");
});

Acknowledgement

When the Reactive Messaging Message gets acknowledged, the associated JMS Message is acknowledged. As JMS acknowledgement is blocking, this acknowledgement is delegated to a worker thread.

Configuration Reference

Attribute (alias) Description Type Mandatory Default
broadcast Whether or not the JMS message should be dispatched to multiple consumers boolean false false
client-id The client id String false
connection-factory-name The name of the JMS connection factory (jakarta.jms.ConnectionFactory) to be used. If not set, it uses any exposed JMS connection factory String false
destination The name of the JMS destination. If not set the name of the channel is used String false
destination-type The type of destination. It can be either queue or topic string false queue
durable Set to true to use a durable subscription boolean false false
no-local Enable or disable local delivery boolean false false
password The password to connect to to the JMS server String false
retry Whether to retry on terminal stream errors. boolean false true
retry.initial-delay The initial delay for the retry. string false PT1S
retry.jitter How much the delay jitters as a multiplier between 0 and 1. The formula is current delay * jitter. For example, with a current delay of 2H, a jitter of 0.5 will result in an actual delay somewhere between 1H and 3H. double false 0.5
retry.max-delay The maximum delay string false PT10S
retry.max-retries Maximum number of retries for terminal stream errors. int false 3
selector The JMS selector String false
session-mode The session mode. Accepted values are AUTO_ACKNOWLEDGE, SESSION_TRANSACTED, CLIENT_ACKNOWLEDGE, DUPS_OK_ACKNOWLEDGE String false AUTO_ACKNOWLEDGE
tracing-enabled Whether tracing is enabled (default) or disabled boolean false true
username The username to connect to to the JMS server String false