Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/gatling/gatling.io-doc/llms.txt

Use this file to discover all available pages before exploring further.

Gatling’s JMS (Java Message Service) support enables you to load test message-oriented middleware such as ActiveMQ, IBM MQ, and any broker that exposes a JMS-compatible API. You can model both fire-and-forget sends and synchronous request-reply patterns, then validate the content of reply messages using the same rich check API used for HTTP. JMS support was originally contributed by Jason Koch.
The JMS protocol is not supported by the JavaScript SDK. If this matters to your project, vote for it on the public roadmap.

Prerequisites

Imports

The JMS SDK is not imported by default. Add the following imports to your simulation:
import io.gatling.javaapi.jms.*;
import static io.gatling.javaapi.jms.JmsDsl.*;

JMS Client Implementation

JMS is an API specification—you must provide a broker-specific client implementation on the classpath. For example, when targeting ActiveMQ:
Maven
<dependency>
  <groupId>org.apache.activemq</groupId>
  <artifactId>activemq-broker</artifactId>
  <version>5.18.3</version>
  <scope>test</scope>
</dependency>

Jakarta vs. Legacy javax.jms

Since Gatling 3.14.0, Gatling targets the modern jakarta.jms package. If your broker client still uses the legacy javax.jms package, wrap your ConnectionFactory with the adapter:
import com.github.marschall.jakartajmsadapter.JakartaConnectionFactory;

ConnectionFactory wrapped = new JakartaConnectionFactory(legacyConnectionFactory);
Add the adapter dependency:
<dependency>
  <groupId>com.github.marschall</groupId>
  <artifactId>jakarta-jms-adapter</artifactId>
  <version>1.1.0</version>
  <scope>test</scope>
</dependency>

JMS Protocol Configuration

Use the jms object to build a protocol that is later attached to your scenario via protocols(...).

Connection Factory

The connection factory is the only mandatory setting. You can obtain it via a JNDI lookup or by direct instantiation.
Java
JmsProtocolBuilder jmsProtocol = jms
  .connectionFactory(
    jmsJndiConnectionFactory
      .connectionFactoryName("ConnectionFactory")
      .url("tcp://localhost:61616")
      .credentials("user", "password") // optional
      .contextFactory("org.apache.activemq.jndi.ActiveMQInitialContextFactory")
  );
Scala
val jmsConfig = jms
  .connectionFactory(
    jmsJndiConnectionFactory
      .connectionFactoryName("ConnectionFactory")
      .url("tcp://localhost:61616")
      .contextFactory("org.apache.activemq.jndi.ActiveMQInitialContextFactory")
  )

Additional Protocol Options

Java
jms
  .connectionFactory(factory)
  .useNonPersistentDeliveryMode()  // use NON_PERSISTENT delivery (this is the default)
  .usePersistentDeliveryMode()     // use PERSISTENT delivery
  .listenerThreadCount(5)          // listener thread count (default 1; increase for some brokers like IBM MQ)
  .replyTimeout(1000)              // max ms to wait for a reply (default 20 000)
  .messageMatcher(...)             // custom correlation strategy
  .matchByMessageId()              // correlate reply by JMSMessageID (default)
  .matchByCorrelationId()          // correlate reply by JMSCorrelationID

JMS Requests

Use jms("requestName") as the entry point for all JMS actions.

Request Types

requestReply

Sends a message and waits for a correlated reply. Response time covers the full round trip.

send

Fire-and-forget. Sends a message without waiting for a reply. Useful for one-way flows.

Destinations

Specify the target destination with queue("queueName"):
jms("send order")
  .requestReply()
  .queue("orders.input")

jms("publish event")
  .send()
  .queue("events.out")
For requestReply, specify where the reply is expected:
jms("order request")
  .requestReply()
  .queue("orders.input")
  .replyQueue("orders.output")           // static reply queue
  .noJmsReplyTo()                        // suppress JMSReplyTo header
  .selector("correlationId = '#{cid}'")  // JMS message selector on reply queue
To measure arrival time on a destination other than the reply queue, use trackerDestination(JmsDestination).

Message Types

jms("send text").send().queue("q").textMessage("Hello, #{username}!")

Extra Message Options

jms("labeled message")
  .send()
  .queue("q")
  .textMessage("body")
  .jmsType("ORDER")                       // sets JMSType header
  .property("priority", "#{level}")       // sets an application property

JMS Checks

Checks validate the content of reply messages. The following check types are supported:

Body checks

bodyBytes, bodyLength, bodyString, substring

Path-based checks

jsonPath, jmesPath, xpath

JMS property check

jmsProperty("propertyName") — inspects message properties on the reply

Simple check

simpleCheck — a boolean predicate over the raw Message

JMS Property Check

Java
jms("get status")
  .requestReply()
  .queue("requests")
  .textMessage("#{requestBody}")
  .check(jmsProperty("status").is("200"))
Scala
jms("get status")
  .requestReply
  .queue("requests")
  .textMessage("#{requestBody}")
  .check(jmsProperty("status").is("200"))

Simple Check

Java
jms("validate message")
  .requestReply()
  .queue("q")
  .textMessage("ping")
  .check(simpleCheck(message -> {
    TextMessage text = (TextMessage) message;
    return text.getText().contains("pong");
  }))
Scala
jms("validate message")
  .requestReply
  .queue("q")
  .textMessage("ping")
  .check(simpleCheck(message => message.asInstanceOf[TextMessage].getText.contains("pong")))

Full Example

The following example targets a local ActiveMQ instance, sends a text message to "jmstestq", and validates the reply body.
import io.gatling.javaapi.core.*;
import io.gatling.javaapi.jms.*;
import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.jms.JmsDsl.*;
import org.apache.activemq.ActiveMQConnectionFactory;

public class JmsSimulation extends Simulation {

  JmsProtocolBuilder jmsProtocol = jms
    .connectionFactory(new ActiveMQConnectionFactory("tcp://localhost:61616"))
    .replyTimeout(60_000);

  ScenarioBuilder scn = scenario("JMS load test")
    .exec(
      jms("request reply test")
        .requestReply()
        .queue("jmstestq")
        .textMessage("Hello from Gatling!")
        .check(bodyString().is("Hello back!"))
    );

  { setUp(scn.injectOpen(atOnceUsers(5))).protocols(jmsProtocol); }
}

Build docs developers (and LLMs) love