diff --git a/base-java/Readme.md b/base-java/Readme.md
new file mode 100644
index 00000000..b889cb9d
--- /dev/null
+++ b/base-java/Readme.md
@@ -0,0 +1,142 @@
+# IBM MQ Base Java Samples
+
+This project provides a set of base Java samples for interacting with IBM MQ using the IBM MQ classes for Java (non-JMS). These include basic examples for put/get, publish/subscribe, and request/response messaging patterns.
+
+## Samples Included
+
+Each sample is located under:
+
+```
+src/main/java/com/ibm/mq/samples/java/
+```
+
+- `BasicPut.java` – Puts a message onto a queue
+- `BasicGet.java` – Gets a message from a queue
+- `BasicPub.java` – Publishes a message to a topic
+- `BasicSub.java` – Subscribes and receives messages from a topic
+- `BasicRequest.java` – Sends a message with a dynamic reply-to queue
+- `BasicResponse.java` – Responds to requests received from a queue
+
+## Prerequisites
+
+- Java 8 or higher
+- Apache Maven
+- IBM MQ installed and running (locally or remotely)
+
+## Project Setup
+
+This is a standard Maven project. All dependencies and build instructions are managed through `pom.xml`.
+
+### Building the Project
+
+To build the project and download dependencies:
+
+```bash
+mvn clean package
+```
+## Running the Samples
+
+Ensure that your environment configuration file (`env.json`) is properly set up. Example:
+
+```json
+{
+ "MQ_ENDPOINTS": [
+ {
+ "QMGR": "QM1",
+ "HOST": "localhost",
+ "PORT": 1414,
+ "CHANNEL": "DEV.APP.SVRCONN",
+ "APP_USER": "app",
+ "APP_PASSWORD": "passw0rd",
+ "QUEUE_NAME": "DEV.QUEUE.1",
+ "BACKOUT_QUEUE": "DEV.QUEUE.2",
+ "MODEL_QUEUE_NAME": "DEV.APP.MODEL.QUEUE",
+ "DYNAMIC_QUEUE_PREFIX": "APP.REPLIES.*",
+ "TOPIC_NAME": "dev/"
+ }
+ ]
+}
+```
+## Using a CCDT File
+
+Instead of manually specifying connection parameters in `env.json`, you can use a **Client Channel Definition Table (CCDT)** JSON file to define connection configurations. This is useful when connecting to IBM MQ instances in cloud or enterprise environments.
+
+Set the environment variable `MQCCDTURL` to point to the CCDT file:
+
+```bash
+export MQCCDTURL=file:/absolute/path/to/ccdt.json
+```
+
+> **Note (Windows):** Use `set` instead of `export`:
+>
+> ```cmd
+> set MQCCDTURL=file:C:\path\to\ccdt.json
+> ```
+
+The sample will detect `MQCCDTURL` and automatically use it for connection settings. When `MQCCDTURL` is set and starts with `file://`, the program prioritizes CCDT-based configuration and skips `host`, `channel`, and `port` in `env.json`.
+
+Make sure your CCDT file defines the appropriate connection information such as **channel name**, **queue manager**, and **connection name list**.
+
+
+## Run Instructions
+
+### Put/Get
+
+```bash
+mvn exec:java -Dexec.mainClass="com.ibm.mq.samples.java.BasicPut" -Dexec.args="env.json"
+mvn exec:java -Dexec.mainClass="com.ibm.mq.samples.java.BasicGet" -Dexec.args="env.json"
+```
+
+### Publish/Subscribe
+
+In the **first terminal (subscriber)**:
+
+```bash
+mvn exec:java -Dexec.mainClass="com.ibm.mq.samples.java.BasicSub" -Dexec.args="env.json"
+```
+
+In the **second terminal (publisher)**:
+
+```bash
+mvn exec:java -Dexec.mainClass="com.ibm.mq.samples.java.BasicPub" -Dexec.args="env.json"
+```
+
+### Request/Response
+
+In the **first terminal (response)**:
+
+```bash
+mvn exec:java -Dexec.mainClass="com.ibm.mq.samples.java.BasicResponse" -Dexec.args="env.json"
+```
+
+In the **second terminal (request)**:
+
+```bash
+mvn exec:java -Dexec.mainClass="com.ibm.mq.samples.java.BasicRequest" -Dexec.args="env.json"
+```
+### Terminal 1: Run the Request Sample
+
+1. **Compile** the `BasicRequest.java` file using the required JAR dependencies.
+2. **Run** the `BasicRequest` class.
+3. The requester sends a message and waits for a response.
+4. If `REPLY_QUEUE_NAME` is set, that queue is used for replies; otherwise, a temporary queue is created.
+5. Optionally, set the `REQUEST_MESSAGE_EXPIRY` environment variable to define how long the request is valid.
+
+---
+
+### Terminal 2: Run the Response Sample
+
+1. **Compile** the `BasicResponse.java` file with the same JAR dependencies.
+2. **Run** the `BasicResponse` class.
+3. The responder listens on a queue, processes incoming messages, and sends replies to the specified reply-to queue.
+4. It continues running until manually stopped or it times out.
+5. You can set the `RESPONDER_INACTIVITY_TIMEOUT` environment variable to control how long it waits for new messages before exiting.
+
+---
+## Notes
+
+- The environment can be configured using either `env.json` or a CCDT file via the `MQCCDTURL` environment variable.
+- Each sample reads from the provided `env.json` to extract connection information for the queue manager.
+- Samples like `BasicResponse` and `BasicSub` are long-running and wait for messages indefinitely until stopped.
+- Make sure all relevant queues and topics are pre-created in your IBM MQ queue manager.
+
diff --git a/base-java/pom.xml b/base-java/pom.xml
new file mode 100644
index 00000000..7932c5d4
--- /dev/null
+++ b/base-java/pom.xml
@@ -0,0 +1,55 @@
+
+ 4.0.0
+
+ com.ibm.mq.samples
+ mq-java-base-consumer
+ 1.0.0
+ jar
+
+
+ 1.8
+ 1.8
+
+
+
+
+
+ com.ibm.mq
+ com.ibm.mq.allclient
+ 9.4.3.0
+
+
+
+
+ org.json
+ json
+ 20240303
+
+
+
+
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base-java/src/main/java/com/ibm/mq/samples/java/BasicGet.java b/base-java/src/main/java/com/ibm/mq/samples/java/BasicGet.java
new file mode 100644
index 00000000..e7a77783
--- /dev/null
+++ b/base-java/src/main/java/com/ibm/mq/samples/java/BasicGet.java
@@ -0,0 +1,133 @@
+package com.ibm.mq.samples.java;
+
+import com.ibm.mq.*;
+import com.ibm.mq.constants.MQConstants;
+import org.json.*;
+
+import java.io.FileReader;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Hashtable;
+
+public class BasicGet {
+
+ private static class MQDetails {
+ String QMGR;
+ String QUEUE_NAME;
+ String HOST;
+ String PORT;
+ String CHANNEL;
+ String USER;
+ String PASSWORD;
+ String KEY_REPOSITORY;
+ String CIPHER;
+ }
+
+ private static JSONArray endpoints;
+
+ public static void main(String[] args) {
+ loadEnv("env.json");
+
+ for (int i = 0; i < endpoints.length(); i++) {
+ System.out.println("Processing endpoint " + i);
+ JSONObject point = endpoints.getJSONObject(i);
+ MQDetails details = buildMQDetails(point);
+ processEndpoint(details);
+ }
+
+ System.out.println("Sample MQ GET application ending");
+ }
+
+ private static void loadEnv(String path) {
+ try {
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+ JSONObject env = new JSONObject(content);
+ endpoints = env.getJSONArray("MQ_ENDPOINTS");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static MQDetails buildMQDetails(JSONObject endpoint) {
+ MQDetails mq = new MQDetails();
+ mq.QMGR = endpoint.getString("QMGR");
+ mq.QUEUE_NAME = endpoint.getString("QUEUE_NAME");
+ mq.HOST = endpoint.getString("HOST");
+ mq.PORT = String.valueOf(endpoint.getInt("PORT"));
+ mq.CHANNEL = endpoint.getString("CHANNEL");
+ mq.USER = endpoint.getString("APP_USER");
+ mq.PASSWORD = endpoint.getString("APP_PASSWORD");
+ mq.KEY_REPOSITORY = endpoint.optString("KEY_REPOSITORY", "");
+ mq.CIPHER = endpoint.optString("CIPHER", "");
+ return mq;
+ }
+
+ private static void processEndpoint(MQDetails details) {
+ MQQueueManager qMgr = null;
+ MQQueue queue = null;
+
+ try {
+ Hashtable props = new Hashtable<>();
+ String ccdtUrl = System.getenv("MQCCDTURL");
+
+ if (ccdtUrl != null && ccdtUrl.startsWith("file://")) {
+ String ccdtPath = ccdtUrl.replace("file://", "");
+ System.setProperty("MQCCDTURL", ccdtPath);
+ System.out.println("Using CCDT at: " + ccdtPath);
+ } else {
+ props.put(MQConstants.HOST_NAME_PROPERTY, details.HOST);
+ props.put(MQConstants.PORT_PROPERTY, Integer.parseInt(details.PORT));
+ props.put(MQConstants.CHANNEL_PROPERTY, details.CHANNEL);
+ }
+
+ props.put(MQConstants.USER_ID_PROPERTY, details.USER);
+ props.put(MQConstants.PASSWORD_PROPERTY, details.PASSWORD);
+ props.put(MQConstants.TRANSPORT_PROPERTY, MQConstants.TRANSPORT_MQSERIES_CLIENT);
+
+ if (!details.KEY_REPOSITORY.isEmpty()) {
+ props.put(MQConstants.SSL_CIPHER_SUITE_PROPERTY, details.CIPHER);
+ System.setProperty("com.ibm.mq.ssl.keyStore", details.KEY_REPOSITORY);
+ System.setProperty("com.ibm.mq.ssl.keyStorePassword", "");
+ }
+
+ qMgr = new MQQueueManager(details.QMGR, props);
+ System.out.println("Connected to queue manager: " + details.QMGR);
+
+ int openOptions = MQConstants.MQOO_INPUT_AS_Q_DEF;
+ queue = qMgr.accessQueue(details.QUEUE_NAME, openOptions);
+
+ boolean keepReading = true;
+ while (keepReading) {
+ MQMessage msg = new MQMessage();
+ MQGetMessageOptions gmo = new MQGetMessageOptions();
+ gmo.options = MQConstants.MQGMO_NO_WAIT |
+ MQConstants.MQGMO_CONVERT |
+ MQConstants.MQGMO_FAIL_IF_QUIESCING;
+
+ try {
+ queue.get(msg, gmo);
+ String str = msg.readStringOfByteLength(msg.getDataLength());
+ System.out.println("Received message: " + str);
+ } catch (MQException mqe) {
+ if (mqe.reasonCode == MQConstants.MQRC_NO_MSG_AVAILABLE) {
+ keepReading = false;
+ System.out.println("No more messages.");
+ } else {
+ System.err.println("Error retrieving message: " + mqe);
+ keepReading = false;
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (queue != null) queue.close();
+ if (qMgr != null) qMgr.disconnect();
+ } catch (MQException me) {
+ me.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/base-java/src/main/java/com/ibm/mq/samples/java/BasicPub.java b/base-java/src/main/java/com/ibm/mq/samples/java/BasicPub.java
new file mode 100644
index 00000000..d0748ba7
--- /dev/null
+++ b/base-java/src/main/java/com/ibm/mq/samples/java/BasicPub.java
@@ -0,0 +1,128 @@
+package com.ibm.mq.samples.java;
+import com.ibm.mq.*;
+import com.ibm.mq.constants.MQConstants;
+import org.json.*;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Hashtable;
+
+public class BasicPub {
+
+ private static class MQDetails {
+ String QMGR;
+ String TOPIC_NAME;
+ String HOST;
+ String PORT;
+ String CHANNEL;
+ String USER;
+ String PASSWORD;
+ String KEY_REPOSITORY;
+ String CIPHER;
+ }
+
+ private static MQDetails mqDetails;
+
+ public static void main(String[] args) {
+ loadEnv("env.json");
+ publishToTopic(mqDetails);
+ System.out.println("Sample MQ PUB application ending");
+ }
+
+ private static void loadEnv(String path) {
+ try {
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+ JSONObject env = new JSONObject(content);
+ JSONObject endpoint = env.getJSONArray("MQ_ENDPOINTS").getJSONObject(0);
+
+ mqDetails = new MQDetails();
+ mqDetails.QMGR = endpoint.getString("QMGR");
+ mqDetails.TOPIC_NAME = endpoint.getString("TOPIC_NAME");
+ mqDetails.HOST = endpoint.getString("HOST");
+ mqDetails.PORT = String.valueOf(endpoint.getInt("PORT"));
+ mqDetails.CHANNEL = endpoint.getString("CHANNEL");
+ mqDetails.USER = endpoint.getString("APP_USER");
+ mqDetails.PASSWORD = endpoint.getString("APP_PASSWORD");
+ mqDetails.KEY_REPOSITORY = endpoint.optString("KEY_REPOSITORY", "");
+ mqDetails.CIPHER = endpoint.optString("CIPHER", "");
+
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void publishToTopic(MQDetails d) {
+ MQQueueManager qMgr = null;
+ MQTopic topic = null;
+
+ try {
+ Hashtable props = new Hashtable<>();
+
+ String ccdtUrl = System.getenv("MQCCDTURL");
+ if (ccdtUrl != null && ccdtUrl.startsWith("file://")) {
+ String ccdtPath = ccdtUrl.replace("file://", "");
+ System.setProperty("MQCCDTURL", ccdtPath);
+ System.out.println("Using CCDT at: " + ccdtPath);
+ } else {
+ props.put(MQConstants.HOST_NAME_PROPERTY, d.HOST);
+ props.put(MQConstants.PORT_PROPERTY, Integer.parseInt(d.PORT));
+ props.put(MQConstants.CHANNEL_PROPERTY, d.CHANNEL);
+ }
+
+ props.put(MQConstants.USER_ID_PROPERTY, d.USER);
+ props.put(MQConstants.PASSWORD_PROPERTY, d.PASSWORD);
+ props.put(MQConstants.TRANSPORT_PROPERTY, MQConstants.TRANSPORT_MQSERIES_CLIENT);
+
+ if (!d.KEY_REPOSITORY.isEmpty()) {
+ props.put(MQConstants.SSL_CIPHER_SUITE_PROPERTY, d.CIPHER);
+ System.setProperty("com.ibm.mq.ssl.keyStore", d.KEY_REPOSITORY);
+ System.setProperty("com.ibm.mq.ssl.keyStorePassword", "");
+ }
+
+ qMgr = new MQQueueManager(d.QMGR, props);
+ System.out.println("Connected to queue manager: " + d.QMGR);
+
+ // Access using topic object name, not just string
+ topic = qMgr.accessTopic(
+ d.TOPIC_NAME,
+ null, // Topic Object defined in MQ
+ MQConstants.MQTOPIC_OPEN_AS_PUBLICATION,
+ MQConstants.MQOO_OUTPUT
+ );
+
+ MQMessage msg = new MQMessage();
+ msg.format = MQConstants.MQFMT_STRING;
+
+ String payload = "{\"Greeting\": \"Hello from Java publisher at " + java.time.Instant.now() + "\"}";
+ msg.writeString(payload);
+
+ MQPutMessageOptions pmo = new MQPutMessageOptions();
+ pmo.options = MQConstants.MQPMO_NO_SYNCPOINT |
+ MQConstants.MQPMO_NEW_MSG_ID |
+ MQConstants.MQPMO_NEW_CORREL_ID |
+ MQConstants.MQPMO_WARN_IF_NO_SUBS_MATCHED;
+
+ topic.put(msg, pmo);
+
+ //System.out.println("Published message to topic object: DEV.BASE.TOPIC");
+ System.out.println("Message content: " + payload);
+
+ } catch (MQException mqe) {
+ if (mqe.reasonCode == MQConstants.MQRC_NO_SUBS_MATCHED) {
+ System.out.println("Warning: No subscribers matched the topic.");
+ } else {
+ mqe.printStackTrace();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (topic != null) topic.close();
+ if (qMgr != null) qMgr.disconnect();
+ } catch (MQException me) {
+ me.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/base-java/src/main/java/com/ibm/mq/samples/java/BasicPut.java b/base-java/src/main/java/com/ibm/mq/samples/java/BasicPut.java
new file mode 100644
index 00000000..c87bcb0a
--- /dev/null
+++ b/base-java/src/main/java/com/ibm/mq/samples/java/BasicPut.java
@@ -0,0 +1,122 @@
+package com.ibm.mq.samples.java;
+import com.ibm.mq.*;
+import com.ibm.mq.constants.MQConstants;
+import org.json.*;
+
+import java.io.FileReader;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Hashtable;
+
+public class BasicPut {
+
+ private static class MQDetails {
+ String QMGR;
+ String QUEUE_NAME;
+ String HOST;
+ String PORT;
+ String CHANNEL;
+ String USER;
+ String PASSWORD;
+ String KEY_REPOSITORY;
+ String CIPHER;
+ }
+
+ private static JSONArray endpoints;
+
+ public static void main(String[] args) {
+ loadEnv("env.json");
+
+ for (int i = 0; i < endpoints.length(); i++) {
+ System.out.println("Processing endpoint " + i);
+ JSONObject point = endpoints.getJSONObject(i);
+ MQDetails details = buildMQDetails(point);
+ processEndpoint(details);
+ }
+
+ System.out.println("Sample MQ PUT application ending");
+ System.exit(0);
+ }
+
+ private static void loadEnv(String path) {
+ try {
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+ JSONObject env = new JSONObject(content);
+ endpoints = env.getJSONArray("MQ_ENDPOINTS");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static MQDetails buildMQDetails(JSONObject endpoint) {
+ MQDetails mq = new MQDetails();
+ mq.QMGR = endpoint.getString("QMGR");
+ mq.QUEUE_NAME = endpoint.getString("QUEUE_NAME");
+ mq.HOST = endpoint.getString("HOST");
+ mq.PORT = String.valueOf(endpoint.getInt("PORT"));
+ mq.CHANNEL = endpoint.getString("CHANNEL");
+ mq.USER = endpoint.getString("APP_USER");
+ mq.PASSWORD = endpoint.getString("APP_PASSWORD");
+ mq.KEY_REPOSITORY = endpoint.optString("KEY_REPOSITORY", "");
+ mq.CIPHER = endpoint.optString("CIPHER", "");
+ return mq;
+ }
+
+ private static void processEndpoint(MQDetails details) {
+ MQQueueManager qMgr = null;
+ MQQueue queue = null;
+
+ try {
+ Hashtable props = new Hashtable<>();
+ String ccdtUrl = System.getenv("MQCCDTURL");
+
+ if (ccdtUrl != null && ccdtUrl.startsWith("file://")) {
+ String ccdtPath = ccdtUrl.replace("file://", "");
+ System.setProperty("MQCCDTURL", ccdtPath);
+ System.out.println("Using CCDT at: " + ccdtPath);
+ } else {
+ props.put(MQConstants.HOST_NAME_PROPERTY, details.HOST);
+ props.put(MQConstants.PORT_PROPERTY, Integer.parseInt(details.PORT));
+ props.put(MQConstants.CHANNEL_PROPERTY, details.CHANNEL);
+ }
+
+ props.put(MQConstants.USER_ID_PROPERTY, details.USER);
+ props.put(MQConstants.PASSWORD_PROPERTY, details.PASSWORD);
+ props.put(MQConstants.TRANSPORT_PROPERTY, MQConstants.TRANSPORT_MQSERIES_CLIENT);
+
+ if (!details.KEY_REPOSITORY.isEmpty()) {
+ props.put(MQConstants.SSL_CIPHER_SUITE_PROPERTY, details.CIPHER);
+ System.setProperty("com.ibm.mq.ssl.keyStore", details.KEY_REPOSITORY);
+ System.setProperty("com.ibm.mq.ssl.keyStorePassword", "");
+ }
+
+ qMgr = new MQQueueManager(details.QMGR, props);
+ System.out.println("Connected to queue manager: " + details.QMGR);
+
+ int openOptions = MQConstants.MQOO_OUTPUT;
+ queue = qMgr.accessQueue(details.QUEUE_NAME, openOptions);
+
+ MQMessage msg = new MQMessage();
+ msg.format = MQConstants.MQFMT_STRING;
+
+ // Hardcoded message body for simplicity
+ String payload = "{\"greeting\": \"Hello from BasicPut.java\"}";
+ msg.writeString(payload);
+
+ MQPutMessageOptions pmo = new MQPutMessageOptions();
+ queue.put(msg, pmo);
+
+ System.out.println("Message put successfully: " + payload);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (queue != null) queue.close();
+ if (qMgr != null) qMgr.disconnect();
+ } catch (MQException me) {
+ me.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/base-java/src/main/java/com/ibm/mq/samples/java/BasicRequest.java b/base-java/src/main/java/com/ibm/mq/samples/java/BasicRequest.java
new file mode 100644
index 00000000..3b458cab
--- /dev/null
+++ b/base-java/src/main/java/com/ibm/mq/samples/java/BasicRequest.java
@@ -0,0 +1,123 @@
+package com.ibm.mq.samples.java;
+import com.ibm.mq.*;
+import com.ibm.mq.constants.MQConstants;
+import org.json.JSONObject;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.Instant;
+import java.util.Hashtable;
+
+public class BasicRequest {
+
+ static class MQDetails {
+ String QMGR;
+ String HOST;
+ int PORT;
+ String CHANNEL;
+ String APP_USER;
+ String APP_PASSWORD;
+ String QUEUE_NAME;
+ String MODEL_QUEUE_NAME;
+ String DYNAMIC_QUEUE_PREFIX;
+ }
+
+ static MQDetails mqDetails;
+
+ public static void main(String[] args) {
+ loadEnv("env.json");
+ sendRequestAndReceiveReply(mqDetails);
+ System.out.println("Sample MQ requester application ending");
+ }
+
+ private static void loadEnv(String path) {
+ try {
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+ JSONObject endpoint = new JSONObject(content)
+ .getJSONArray("MQ_ENDPOINTS").getJSONObject(0);
+
+ mqDetails = new MQDetails();
+ mqDetails.QMGR = endpoint.getString("QMGR");
+ mqDetails.HOST = endpoint.getString("HOST");
+ mqDetails.PORT = endpoint.getInt("PORT");
+ mqDetails.CHANNEL = endpoint.getString("CHANNEL");
+ mqDetails.APP_USER = endpoint.getString("APP_USER");
+ mqDetails.APP_PASSWORD = endpoint.getString("APP_PASSWORD");
+ mqDetails.QUEUE_NAME = endpoint.getString("QUEUE_NAME");
+ mqDetails.MODEL_QUEUE_NAME = endpoint.getString("MODEL_QUEUE_NAME");
+ mqDetails.DYNAMIC_QUEUE_PREFIX = endpoint.getString("DYNAMIC_QUEUE_PREFIX");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void sendRequestAndReceiveReply(MQDetails d) {
+ MQQueueManager qMgr = null;
+ MQQueue requestQueue = null;
+ MQQueue replyQueue = null;
+
+ try {
+ Hashtable props = new Hashtable<>();
+ props.put(MQConstants.HOST_NAME_PROPERTY, d.HOST);
+ props.put(MQConstants.PORT_PROPERTY, d.PORT);
+ props.put(MQConstants.CHANNEL_PROPERTY, d.CHANNEL);
+ props.put(MQConstants.USER_ID_PROPERTY, d.APP_USER);
+ props.put(MQConstants.PASSWORD_PROPERTY, d.APP_PASSWORD);
+ props.put(MQConstants.TRANSPORT_PROPERTY, MQConstants.TRANSPORT_MQSERIES_CLIENT);
+
+ qMgr = new MQQueueManager(d.QMGR, props);
+ System.out.println("Connected to queue manager: " + d.QMGR);
+
+ replyQueue = qMgr.accessQueue(
+ d.MODEL_QUEUE_NAME,
+ MQConstants.MQOO_INPUT_EXCLUSIVE,
+ null,
+ d.DYNAMIC_QUEUE_PREFIX,
+ null
+ );
+ String dynamicReplyQueueName = replyQueue.getName();
+ System.out.println("Opened dynamic reply-to queue: " + dynamicReplyQueueName);
+
+ requestQueue = qMgr.accessQueue(d.QUEUE_NAME, MQConstants.MQOO_OUTPUT);
+
+ MQMessage request = new MQMessage();
+ request.format = MQConstants.MQFMT_STRING;
+ request.replyToQueueName = dynamicReplyQueueName;
+ request.messageType = MQConstants.MQMT_REQUEST;
+
+ String payload = "{\"Greeting\": \"Hello from Java Requester at " + Instant.now() + "\"}";
+ request.writeString(payload);
+
+ MQPutMessageOptions pmo = new MQPutMessageOptions();
+ pmo.options = MQConstants.MQPMO_NO_SYNCPOINT;
+
+ requestQueue.put(request, pmo);
+ System.out.println("Sent request message to queue: " + d.QUEUE_NAME);
+ System.out.println("Waiting for reply on: " + dynamicReplyQueueName);
+
+ MQMessage response = new MQMessage();
+ MQGetMessageOptions gmo = new MQGetMessageOptions();
+ gmo.options = MQConstants.MQGMO_WAIT | MQConstants.MQGMO_CONVERT;
+ gmo.waitInterval = 10000;
+
+ replyQueue.get(response, gmo);
+ String replyText = response.readStringOfByteLength(response.getDataLength());
+ System.out.println("Received reply: " + replyText);
+
+ } catch (MQException mqe) {
+ System.err.println("MQ Error - Completion Code: " + mqe.completionCode +
+ " Reason Code: " + mqe.reasonCode);
+ mqe.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (requestQueue != null) requestQueue.close();
+ if (replyQueue != null) replyQueue.close();
+ if (qMgr != null) qMgr.disconnect();
+ } catch (MQException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/base-java/src/main/java/com/ibm/mq/samples/java/BasicResponse.java b/base-java/src/main/java/com/ibm/mq/samples/java/BasicResponse.java
new file mode 100644
index 00000000..81234635
--- /dev/null
+++ b/base-java/src/main/java/com/ibm/mq/samples/java/BasicResponse.java
@@ -0,0 +1,121 @@
+package com.ibm.mq.samples.java;
+import com.ibm.mq.*;
+import com.ibm.mq.constants.MQConstants;
+import org.json.JSONObject;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Hashtable;
+
+public class BasicResponse {
+
+ static class MQDetails {
+ String QMGR;
+ String HOST;
+ int PORT;
+ String CHANNEL;
+ String APP_USER;
+ String APP_PASSWORD;
+ String QUEUE_NAME;
+ }
+
+ static MQDetails mqDetails;
+
+ public static void main(String[] args) {
+ loadEnv("env.json");
+ listenAndRespond(mqDetails);
+ System.out.println("Sample MQ responder application ending");
+ }
+
+ private static void loadEnv(String path) {
+ try {
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+ JSONObject endpoint = new JSONObject(content)
+ .getJSONArray("MQ_ENDPOINTS").getJSONObject(0);
+
+ mqDetails = new MQDetails();
+ mqDetails.QMGR = endpoint.getString("QMGR");
+ mqDetails.HOST = endpoint.getString("HOST");
+ mqDetails.PORT = endpoint.getInt("PORT");
+ mqDetails.CHANNEL = endpoint.getString("CHANNEL");
+ mqDetails.APP_USER = endpoint.getString("APP_USER");
+ mqDetails.APP_PASSWORD = endpoint.getString("APP_PASSWORD");
+ mqDetails.QUEUE_NAME = endpoint.getString("QUEUE_NAME");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void listenAndRespond(MQDetails d) {
+ MQQueueManager qMgr = null;
+ MQQueue requestQueue = null;
+
+ try {
+ Hashtable props = new Hashtable<>();
+ props.put(MQConstants.HOST_NAME_PROPERTY, d.HOST);
+ props.put(MQConstants.PORT_PROPERTY, d.PORT);
+ props.put(MQConstants.CHANNEL_PROPERTY, d.CHANNEL);
+ props.put(MQConstants.USER_ID_PROPERTY, d.APP_USER);
+ props.put(MQConstants.PASSWORD_PROPERTY, d.APP_PASSWORD);
+ props.put(MQConstants.TRANSPORT_PROPERTY, MQConstants.TRANSPORT_MQSERIES_CLIENT);
+
+ qMgr = new MQQueueManager(d.QMGR, props);
+ System.out.println("Connected to queue manager: " + d.QMGR);
+
+ requestQueue = qMgr.accessQueue(
+ d.QUEUE_NAME,
+ MQConstants.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_OUTPUT
+ );
+
+ MQGetMessageOptions gmo = new MQGetMessageOptions();
+ gmo.options = MQConstants.MQGMO_WAIT | MQConstants.MQGMO_CONVERT;
+ gmo.waitInterval = 10000;
+
+ while (true) {
+ MQMessage request = new MQMessage();
+ try {
+ requestQueue.get(request, gmo);
+ String msgText = request.readStringOfByteLength(request.getDataLength());
+ System.out.println("Received request: " + msgText);
+
+ String replyToQueueName = request.replyToQueueName;
+ if (replyToQueueName != null && !replyToQueueName.isEmpty()) {
+ MQQueue replyQueue = qMgr.accessQueue(replyToQueueName, MQConstants.MQOO_OUTPUT);
+
+ MQMessage reply = new MQMessage();
+ reply.format = MQConstants.MQFMT_STRING;
+ reply.correlationId = request.messageId;
+
+ JSONObject replyJson = new JSONObject();
+ replyJson.put("Response", "Hello from Java Responder!");
+ reply.writeString(replyJson.toString());
+
+ MQPutMessageOptions pmo = new MQPutMessageOptions();
+ pmo.options = MQConstants.MQPMO_NO_SYNCPOINT;
+
+ replyQueue.put(reply, pmo);
+ System.out.println("Sent reply to: " + replyToQueueName);
+ replyQueue.close();
+ }
+ } catch (MQException mqe) {
+ if (mqe.reasonCode == MQConstants.MQRC_NO_MSG_AVAILABLE) {
+ System.out.println("No message received. Exiting.");
+ break;
+ } else {
+ throw mqe;
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (requestQueue != null) requestQueue.close();
+ if (qMgr != null) qMgr.disconnect();
+ } catch (MQException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/base-java/src/main/java/com/ibm/mq/samples/java/BasicSub.java b/base-java/src/main/java/com/ibm/mq/samples/java/BasicSub.java
new file mode 100644
index 00000000..b517a6b1
--- /dev/null
+++ b/base-java/src/main/java/com/ibm/mq/samples/java/BasicSub.java
@@ -0,0 +1,133 @@
+package com.ibm.mq.samples.java;
+import com.ibm.mq.*;
+import com.ibm.mq.constants.MQConstants;
+import org.json.*;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Hashtable;
+
+public class BasicSub {
+
+ private static class MQDetails {
+ String QMGR;
+ String SUB_NAME;
+ String QUEUE_NAME;
+ String HOST;
+ String PORT;
+ String CHANNEL;
+ String USER;
+ String PASSWORD;
+ String KEY_REPOSITORY;
+ String CIPHER;
+ }
+
+ private static MQDetails mqDetails;
+
+ public static void main(String[] args) {
+ loadEnv("env.json");
+ subscribeToQueue(mqDetails);
+ System.out.println("Sample MQ durable SUB application ending");
+ }
+
+ private static void loadEnv(String path) {
+ try {
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+ JSONObject env = new JSONObject(content);
+ JSONObject endpoint = env.getJSONArray("MQ_ENDPOINTS").getJSONObject(0);
+
+ mqDetails = new MQDetails();
+ mqDetails.QMGR = endpoint.getString("QMGR");
+ mqDetails.SUB_NAME = endpoint.getString("SUB_NAME");
+ mqDetails.QUEUE_NAME = endpoint.getString("QUEUE_NAME"); // ✅ Fix
+ mqDetails.HOST = endpoint.getString("HOST");
+ mqDetails.PORT = String.valueOf(endpoint.getInt("PORT"));
+ mqDetails.CHANNEL = endpoint.getString("CHANNEL");
+ mqDetails.USER = endpoint.getString("APP_USER");
+ mqDetails.PASSWORD = endpoint.getString("APP_PASSWORD");
+ mqDetails.KEY_REPOSITORY = endpoint.optString("KEY_REPOSITORY", "");
+ mqDetails.CIPHER = endpoint.optString("CIPHER", "");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void subscribeToQueue(MQDetails d) {
+ MQQueueManager qMgr = null;
+ MQQueue queue = null;
+
+ try {
+ Hashtable props = new Hashtable<>();
+
+ String ccdtUrl = System.getenv("MQCCDTURL");
+ if (ccdtUrl != null && ccdtUrl.startsWith("file://")) {
+ String ccdtPath = ccdtUrl.replace("file://", "");
+ System.setProperty("MQCCDTURL", ccdtPath);
+ System.out.println("Using CCDT at: " + ccdtPath);
+ } else {
+ props.put(MQConstants.HOST_NAME_PROPERTY, d.HOST);
+ props.put(MQConstants.PORT_PROPERTY, Integer.parseInt(d.PORT));
+ props.put(MQConstants.CHANNEL_PROPERTY, d.CHANNEL);
+ }
+
+ props.put(MQConstants.USER_ID_PROPERTY, d.USER);
+ props.put(MQConstants.PASSWORD_PROPERTY, d.PASSWORD);
+ props.put(MQConstants.TRANSPORT_PROPERTY, MQConstants.TRANSPORT_MQSERIES_CLIENT);
+
+ if (!d.KEY_REPOSITORY.isEmpty()) {
+ props.put(MQConstants.SSL_CIPHER_SUITE_PROPERTY, d.CIPHER);
+ System.setProperty("com.ibm.mq.ssl.keyStore", d.KEY_REPOSITORY);
+ System.setProperty("com.ibm.mq.ssl.keyStorePassword", "");
+ }
+
+ qMgr = new MQQueueManager(d.QMGR, props);
+ System.out.println("Connected to queue manager: " + d.QMGR);
+
+ int openOptions = MQConstants.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_FAIL_IF_QUIESCING;
+ queue = qMgr.accessQueue(d.QUEUE_NAME, openOptions);
+
+ receiveMessages(queue);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (queue != null) queue.close();
+ if (qMgr != null) qMgr.disconnect();
+ } catch (MQException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private static void receiveMessages(MQQueue queue) {
+ try {
+ MQMessage msg = new MQMessage();
+ MQGetMessageOptions gmo = new MQGetMessageOptions();
+ gmo.options = MQConstants.MQGMO_NO_SYNCPOINT |
+ MQConstants.MQGMO_WAIT |
+ MQConstants.MQGMO_CONVERT |
+ MQConstants.MQGMO_FAIL_IF_QUIESCING;
+ gmo.waitInterval = 10000;
+
+ System.out.println("Waiting for messages from durable subscription queue...");
+ while (true) {
+ msg.clearMessage();
+ try {
+ queue.get(msg, gmo);
+ String received = msg.readStringOfByteLength(msg.getDataLength());
+ System.out.println("Received: " + received);
+ } catch (MQException mqe) {
+ if (mqe.reasonCode == MQConstants.MQRC_NO_MSG_AVAILABLE) {
+ System.out.println("No messages. Exiting.");
+ break;
+ } else {
+ throw mqe;
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}