Skip to content
Mahdi Sheikh Hosseini edited this page Aug 1, 2025 · 4 revisions

πŸ“© JMS Integration in MicroFox

MicroFox provides a lightweight, pluggable, and vendor-agnostic JMS layer that allows applications to consume and produce messages via popular brokers like RabbitMQ, Artemis, or any JMS 2.0-compliant provider.
It avoids XML configuration and heavy frameworks by exposing a functional API for both listeners and producers.

βš™οΈ Enabling JMS

To enable jms in your MicroFox application, simply add the following Maven dependency:

<dependency>                                    
    <groupId>ir.moke.microfox</groupId>         
    <artifactId>microfox-jms</artifactId>       
    <version>${microfox.version}</version>      
</dependency>                                   

🧠 Core JMS Concepts

  • No container, no annotations:
    MicroFox uses manual and explicit configuration via simple static registration methods.
  • Multi-broker support:
    Each JMS connection is registered under a unique identity, enabling multiple brokers to coexist.
  • Decoupled consumer/producer:
    Consumers (jmsListener) and producers (jmsProducer) work independently but share the same registered connection factory.
  • Connection retry loop:
    Listeners automatically reconnect using an internal retry mechanism.

🧩 API Overview

// Register a connection factory
JmsFactory.registerConnectionFactory(String identity, ConnectionFactory factory);
// Create a JMS listener
jmsListener(String identity, String destination, DestinationType type, int acknowledgeMode, MessageListener listener);
// Create a JMS producer
jmsProducer(String identity, boolean transacted, int acknowledgeMode, DestinationType type, Consumer<JMSContext> consumer);

πŸ”„ DestinationType can be either QUEUE or TOPIC

πŸ’‘ Environment Variables

MicroFox JMS can be configured entirely via environment variables or .properties files. Below is a list of supported configuration keys:

Key Description Example / Default
MICROFOX_JMS_CONNECTION_RETRY_INTERVAL Delay (ms) between failed connection retry attempts 3000

πŸ‡ RabbitMQ Example

public class RabbitMQTest {
    private static final String IDENTITY = "rabbitmq";
    private static final String QUEUE_NAME = "test";

    @BeforeAll
    public static void init() {
        RMQConnectionFactory factory = new RMQConnectionFactory();
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");
        JmsFactory.registerConnectionFactory(IDENTITY, factory);
    }

    @Test
    public void testConsumer() {
        jmsListener(IDENTITY, QUEUE_NAME, DestinationType.QUEUE, Session.AUTO_ACKNOWLEDGE, new CustomMessageListener());
        sendTestMessage();
    }

    public static void sendTestMessage() {
        jmsProducer(IDENTITY, false, Session.AUTO_ACKNOWLEDGE, DestinationType.QUEUE, context -> {
            Queue queue = context.createQueue(QUEUE_NAME);
            JMSProducer producer = context.createProducer();
            producer.send(queue, context.createTextMessage("Hello RabbitMQ"));
        });
    }
}

πŸš€ Artemis Example

public class ArtemisTest {
    private static final String IDENTITY = "artemis";
    private static final String QUEUE_NAME = "test";

    @BeforeAll
    public static void init() {
        String brokerUrl = "tcp://127.0.0.1:61616";
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerUrl);
        factory.setUser("admin");
        factory.setPassword("adminpass");
        factory.setConnectionTTL(100);
        JmsFactory.registerConnectionFactory(IDENTITY, factory);
    }

    @Test
    public void testConsumer() {
        jmsListener(IDENTITY, QUEUE_NAME, DestinationType.QUEUE, Session.AUTO_ACKNOWLEDGE, new CustomMessageListener());
        sendTestMessage();
    }

    public static void sendTestMessage() {
        jmsProducer(IDENTITY, false, Session.AUTO_ACKNOWLEDGE, DestinationType.QUEUE, context -> {
            Queue queue = context.createQueue(QUEUE_NAME);
            JMSProducer producer = context.createProducer();
            producer.send(queue, context.createTextMessage("Hello Artemis"));
        });
    }
}

βœ… Key Advantages

  • Minimal boilerplate: Explicit and functional style.
  • Multiple brokers: Run RabbitMQ, Artemis, etc., side-by-side.
  • Automatic reconnect: Robust listener behavior with retry on failure.
  • Flexible destination types: Queues and Topics both supported.
  • Ideal for microservices: Easily integrate with asynchronous architectures.

πŸ› οΈ Custom MessageListener

Implement your own listener class by extending javax.jms.MessageListener:

public class CustomMessageListener implements MessageListener {
    @Override
    public void onMessage(Message message) {
        try {
            if (message instanceof TextMessage textMsg) {
                System.out.println("Received: " + textMsg.getText());
            }
        } catch (JMSException e) {
            throw new MicrofoxException(e);
        }
    }
}

Clone this wiki locally