Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JMS-SecondClient (Producer / Publisher)

Java Message Service (JMS) Demonstration

This repository contains the JMS-SecondClient, which acts as the Message Producer / Sender in a Java Message Service (JMS) demonstration.

The accompanying Consumer/Subscriber (JMS-FirstClient) is located in a separate repository. You can find it here:
👉 JMS-FirstClient Repository

Message Broker / Server: Payara Server


Overview and Theory

Java Message Service (JMS) is a Java API that enables distributed communication which is loosely coupled, reliable, and asynchronous. JMS mainly supports two messaging models: Publish/Subscribe (Topic) and Point-to-Point (Queue).

1. Publish / Subscribe Model (Topic)

Theory: The message Publisher creates and sends messages to a Topic. The publisher does not know who or how many subscribers are listening; it simply broadcasts the message.

  • Delivery: Delivered to all active subscribers.
  • Timing: Subscribers usually need to be active at the time of publishing to receive the message (unless using durable subscriptions).

2. Point-to-Point Model (Queue)

Theory: In the Point-to-Point model, messages are sent to a Queue. The message is delivered to exactly one consumer. Even if multiple consumers are listening to the same queue, each message is only processed by a single consumer (load balancing).

  • Delivery: Delivered to exactly one consumer.
  • Timing: Messages are retained in the queue until they are consumed or expire. Producer and Consumer do not need to be active at the same time.

QueueConnection Usage: To use queues, the application uses QueueConnectionFactory to create a QueueConnection. From there, a QueueSession is created. The producer uses a QueueSender to send messages to a specific Queue.

Queue vs. Topic Comparison

Feature Queue (Point-to-Point) Topic (Publish/Subscribe)
Delivery Target Exactly one consumer per message. All active subscribers.
Message Retention Kept in the queue until consumed. Only received by active subscribers at the time.
Coupling Loose timing (asynchronous processing). Tighter timing (broadcast nature).
Primary Goal Load balancing, reliable task execution. Event broadcasting, notifications.

Real-World Use Cases

  • Queue (Point-to-Point): E-commerce Order Processing. When a user places an order, the data is placed in a Queue. You might have 5 worker servers listening to the queue. The queue ensures that a specific order is picked up and processed by exactly one server, preventing duplicate charges or duplicate shipping.
  • Topic (Publish/Subscribe): Stock Price Updates / Chat Rooms. When a stock price changes, the update is published to a Topic. All active trading applications (subscribers) connected to that topic receive the exact same price update simultaneously.

Implementation Code Examples (Producer Side)

Sending to a Queue (QueueConnection)

// 1. Obtain InitialContext
InitialContext ctx = new InitialContext();

// 2. Lookup QueueConnectionFactory and Queue
QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("myQueueConnectionFactory");
Queue queue = (Queue) ctx.lookup("myQueue");

// 3. Create Connection and Session
QueueConnection connection = factory.createQueueConnection();
QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

// 4. Create Sender and Message
QueueSender sender = session.createSender(queue);
TextMessage message = session.createTextMessage("Hello via Queue!");

// 5. Send Message
sender.send(message);

// 6. Clean up
sender.close();
session.close();
connection.close();

Publishing to a Topic (TopicConnection)

// 1. Obtain InitialContext
InitialContext ctx = new InitialContext();

// 2. Lookup TopicConnectionFactory and Topic
TopicConnectionFactory factory = (TopicConnectionFactory) ctx.lookup("myTopicConnectionFactory");
Topic topic = (Topic) ctx.lookup("myTopic");

// 3. Create Connection and Session
TopicConnection connection = factory.createTopicConnection();
TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);

// 4. Create Publisher and Message
TopicPublisher publisher = session.createPublisher(topic);
TextMessage message = session.createTextMessage("Hello via Topic!");

// 5. Publish Message
publisher.publish(message);

// 6. Clean up
publisher.close();
session.close();
connection.close();

Dependencies

This is a standard Maven project using Java 17. The external dependency required is the embedded Payara library, which includes the JMS API and the necessary client components to connect to the Payara Server.

<dependency>
    <groupId>fish.payara.extras</groupId>
    <artifactId>payara-embedded-all</artifactId>
    <version>6.2025.11</version>
</dependency>

Prerequisites

  • Java Development Kit (JDK 17)
  • Payara Server: Must be running for the client to connect and communicate. Ensure resources like myTopicConnectionFactory/myTopic or myQueueConnectionFactory/myQueue are configured on the server.
  • JMS-FirstClient: Ensure you have the JMS-FirstClient running to receive the messages sent by this application.

Troubleshooting & Common Issues

1. Check JDK and Payara Versions

Ensure that your installed JDK version is compatible with your version of Payara Server. Mismatched versions can cause unexpected runtime failures. This project is configured for Java 17.

2. Add VM Options (For Module Access Errors)

If you are using a modern JDK (Java 16 or newer), you might encounter IllegalAccessError or InaccessibleObjectException due to strict module encapsulation. You need to explicitly grant the application access to internal Java APIs.

Add the following arguments to the VM Options in your IDE's Run Configuration:

--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.management/javax.management.openmbean=ALL-UNNAMED --add-opens java.management/javax.management=ALL-UNNAMED

How to Run

  1. Start the Payara Server and verify JNDI resources are configured.
  2. Start the JMS-FirstClient (Consumer) from its repository, so it is ready and waiting to receive messages.
  3. Run this JMS-SecondClient (Producer/Sender).
  4. Start typing messages in the console. You should see those messages appearing instantly in the console of JMS-FirstClient. Type exit to stop the application.

About

This repository contains the JMS-SecondClient, which acts as the Message Producer (Publisher) in a Java Message Service (JMS) Publish/Subscribe messaging model demonstration.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages