diff --git a/.doc_gen/metadata/sqs_metadata.yaml b/.doc_gen/metadata/sqs_metadata.yaml
index 257d4e038ba..0771a1e3cec 100644
--- a/.doc_gen/metadata/sqs_metadata.yaml
+++ b/.doc_gen/metadata/sqs_metadata.yaml
@@ -1116,7 +1116,7 @@ sqs_Scenario_TopicsAndQueues:
sqs_Scenario_WorkWithTags:
title: Work with queue tags and &SQS; using an &AWS; SDK
title_abbrev: Work with queue tags
- synopsis: perform tagging operation with &SQS;
+ synopsis: perform tagging operation with &SQS;.
category: Scenarios
languages:
Java:
@@ -1130,3 +1130,68 @@ sqs_Scenario_WorkWithTags:
- sqs.java2.tag-examples
services:
sqs: {TagQueue, ListQueueTags, UntagQueue}
+sqs_Scenario_UseJMS:
+ title: Use the &SQS; Java Messaging Library to work with the Java Message Service (JMS) interface for &SQS;
+ title_abbrev: Use the &SQS; Java Messaging Library to work with the JMS interface
+ synopsis: use the &SQS; Java Messaging Library to work with the JMS interface.
+ category: Scenarios
+ languages:
+ Java:
+ versions:
+ - sdk_version: 2
+ github: javav2/example_code/sqs
+ sdkguide:
+ excerpts:
+ - description: >-
+ The following examples work with standard &SQS; queues and include:
+
+
+ Sending a text message.
+
+
+ Receiving messages synchronously.
+
+
+ Receiving messages asynchronously.
+
+
+ Receiving messages using CLIENT_ACKNOWLEDGE mode.
+
+
+ Receiving messages using the UNORDERED_ACKNOWLEDGE mode.
+
+
+ Using Spring to inject dependencies.
+
+
+ A utility class that provides common methods used by the other examples.
+
+
+ For more information on using JMS with &SQS;, see the
+ &SQS; Developer Guide.
+ Sending a text message.
+ snippet_tags:
+ - sqs-jms.java2.send-text-message
+ - description: Receiving messages synchronously.
+ snippet_tags:
+ - sqs-jms.java2.receive-message-sync
+ - description: Receiving messages asynchronously.
+ snippet_tags:
+ - sqs-jms.java2.receive-message-async
+ - description: Receiving messages using CLIENT_ACKNOWLEDGE mode.
+ snippet_tags:
+ - sqs-jms.java2.receive-message-sync-client-ack
+ - description: Receiving messages using the UNORDERED_ACKNOWLEDGE mode.
+ snippet_tags:
+ - sqs-jms.java2.receive-message-sync-unordered-ack
+ - description: Using Spring to inject dependencies.
+ snippet_tags:
+ - sqs-jms.java2.spring
+ - description: Spring bean definitions.
+ snippet_files:
+ - javav2/example_code/sqs-jms/src/main/resources/SpringExampleConfiguration.xml.txt
+ - description: A utility class that provides common methods used by the other examples.
+ snippet_files:
+ - javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/SqsJmsExampleUtils.java
+ services:
+ sqs: {CreateQueue, DeleteQueue}
diff --git a/javav2/example_code/sqs-jms/pom.xml b/javav2/example_code/sqs-jms/pom.xml
new file mode 100644
index 00000000000..f9d13824bb4
--- /dev/null
+++ b/javav2/example_code/sqs-jms/pom.xml
@@ -0,0 +1,124 @@
+
+
+ 4.0.0
+ SQSJMSJ2Project
+ SQSJMSJ2Project
+ 1.0-SNAPSHOT
+
+ UTF-8
+ 17
+ 17
+ 17
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.5.2
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ ${java.version}
+ ${java.version}
+
+
+
+
+
+
+
+ software.amazon.awssdk
+ bom
+ 2.29.24
+ pom
+ import
+
+
+ org.apache.logging.log4j
+ log4j-bom
+ 2.23.1
+ pom
+ import
+
+
+
+
+
+ com.amazonaws
+ amazon-sqs-java-messaging-lib
+ 2.1.4
+
+
+ software.amazon.awssdk
+ sso
+
+
+ software.amazon.awssdk
+ ssooidc
+
+
+ org.apache.logging.log4j
+ log4j-core
+
+
+ org.slf4j
+ slf4j-api
+ 2.0.13
+
+
+ org.apache.logging.log4j
+ log4j-slf4j2-impl
+
+
+ org.apache.logging.log4j
+ log4j-1.2-api
+
+
+
+ org.springframework
+ spring-context
+ 6.1.14
+
+
+
+
+ org.springframework
+ spring-beans
+ 6.1.14
+
+
+
+
+ org.springframework
+ spring-core
+ 6.1.14
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.12.0
+ test
+
+
+
+
+ software.amazon.awssdk
+ apache-client
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+
\ No newline at end of file
diff --git a/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/SqsJmsExampleUtils.java b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/SqsJmsExampleUtils.java
new file mode 100644
index 00000000000..71eba0e25cf
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/SqsJmsExampleUtils.java
@@ -0,0 +1,210 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms;
+
+import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper;
+import com.amazon.sqs.javamessaging.ProviderConfiguration;
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.amazon.sqs.javamessaging.SQSConnectionFactory;
+import jakarta.jms.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.core.exception.SdkException;
+import software.amazon.awssdk.services.sqs.SqsClient;
+import software.amazon.awssdk.services.sqs.model.CreateQueueRequest;
+import software.amazon.awssdk.services.sqs.model.QueueAttributeName;
+
+import java.time.Duration;
+import java.util.Base64;
+import java.util.Map;
+
+/**
+ * This utility class provides helper methods for working with Amazon Simple Queue Service (Amazon SQS)
+ * through the Java Message Service (JMS) interface. It contains common operations for managing message
+ * queues and handling message delivery.
+ */
+public class SqsJmsExampleUtils {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SqsJmsExampleUtils.class);
+ public static final Long QUEUE_VISIBILITY_TIMEOUT = 5L;
+
+ /**
+ * This method verifies that a message queue exists and creates it if necessary. The method checks for
+ * an existing queue first to optimize performance.
+ *
+ * @param connection The active connection to the messaging service
+ * @param queueName The name of the queue to verify or create
+ * @param visibilityTimeout The duration in seconds that messages will be hidden after being received
+ * @throws JMSException If there is an error accessing or creating the queue
+ */
+ public static void ensureQueueExists(SQSConnection connection, String queueName, Long visibilityTimeout) throws JMSException {
+ AmazonSQSMessagingClientWrapper client = connection.getWrappedAmazonSQSClient();
+
+ /* In most cases, you can do this with just a 'createQueue' call, but 'getQueueUrl'
+ (called by 'queueExists') is a faster operation for the common case where the queue
+ already exists. Also, many users and roles have permission to call 'getQueueUrl'
+ but don't have permission to call 'createQueue'.
+ */
+ if( !client.queueExists(queueName) ) {
+ CreateQueueRequest createQueueRequest = CreateQueueRequest.builder()
+ .queueName(queueName)
+ .attributes(Map.of(QueueAttributeName.VISIBILITY_TIMEOUT, String.valueOf(visibilityTimeout)))
+ .build();
+ client.createQueue( createQueueRequest );
+ }
+ }
+
+ /**
+ * This method sends a simple text message to a specified message queue. It handles all necessary
+ * setup for the message delivery process.
+ *
+ * @param session The active messaging session used to create and send the message
+ * @param queueName The name of the queue where the message will be sent
+ */
+ public static void sendTextMessage(Session session, String queueName) {
+ // Rest of implementation...
+
+ try {
+ MessageProducer producer = session.createProducer( session.createQueue( queueName) );
+ Message message = session.createTextMessage("Hello world!");
+ producer.send(message);
+ } catch (JMSException e) {
+ LOGGER.error( "Error receiving from SQS", e );
+ }
+ }
+
+ /**
+ * This method processes incoming messages and logs their content based on the message type.
+ * It supports text messages, binary data, and Java objects.
+ *
+ * @param message The message to be processed and logged
+ * @throws JMSException If there is an error reading the message content
+ */
+ public static void handleMessage(Message message) throws JMSException {
+ // Rest of implementation...
+ LOGGER.info( "Got message {}", message.getJMSMessageID() );
+ LOGGER.info( "Content: ");
+ if(message instanceof TextMessage txtMessage) {
+ LOGGER.info( "\t{}", txtMessage.getText() );
+ } else if(message instanceof BytesMessage byteMessage){
+ // Assume the length fits in an int - SQS only supports sizes up to 256k so that
+ // should be true
+ byte[] bytes = new byte[(int)byteMessage.getBodyLength()];
+ byteMessage.readBytes(bytes);
+ LOGGER.info( "\t{}", Base64.getEncoder().encodeToString( bytes ) );
+ } else if( message instanceof ObjectMessage) {
+ ObjectMessage objMessage = (ObjectMessage) message;
+ LOGGER.info( "\t{}", objMessage.getObject() );
+ }
+ }
+
+ /**
+ * This method sets up automatic message processing for a specified queue. It creates a listener
+ * that will receive and handle incoming messages without blocking the main program.
+ *
+ * @param session The active messaging session
+ * @param queueName The name of the queue to monitor
+ * @param connection The active connection to the messaging service
+ */
+ public static void receiveMessagesAsync(Session session, String queueName, Connection connection) {
+ // Rest of implementation...
+ try {
+ // Create a consumer for the queue.
+ MessageConsumer consumer = session.createConsumer(session.createQueue(queueName));
+ // Provide an implementation of the MessageListener interface, which has a single 'onMessage' method.
+ // We use a lambda expression for the implementation.
+ consumer.setMessageListener(message -> {
+ try {
+ SqsJmsExampleUtils.handleMessage(message);
+ message.acknowledge();
+ } catch (JMSException e) {
+ LOGGER.error("Error processing message: {}", e.getMessage());
+ }
+ });
+ // Start receiving incoming messages.
+ connection.start();
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ /**
+ * This method performs cleanup operations after message processing is complete. It receives
+ * any messages in the specified queue, removes the message queue and closes all
+ * active connections to prevent resource leaks.
+ *
+ * @param queueName The name of the queue to be removed
+ * @param visibilityTimeout The duration in seconds that messages are hidden after being received
+ * @throws JMSException If there is an error during the cleanup process
+ */
+ public static void cleanUpExample(String queueName, Long visibilityTimeout) throws JMSException {
+ LOGGER.info("Performing cleanup.");
+
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+
+ try (SQSConnection connection = connectionFactory.createConnection() ) {
+ ensureQueueExists(connection, queueName, visibilityTimeout);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ receiveMessagesAsync(session, queueName, connection);
+
+ SqsClient sqsClient = connection.getWrappedAmazonSQSClient().getAmazonSQSClient();
+ try {
+ String queueUrl = sqsClient.getQueueUrl(b -> b.queueName(queueName)).queueUrl();
+ sqsClient.deleteQueue(b -> b.queueUrl(queueUrl));
+ LOGGER.info("Queue deleted: {}", queueUrl);
+ } catch (SdkException e) {
+ LOGGER.error("Error during SQS operations: ", e);
+ }
+ }
+ LOGGER.info("Clean up: Connection closed");
+ }
+
+ /**
+ * This method creates a background task that sends multiple messages to a specified queue
+ * after waiting for a set time period. The task operates independently to ensure efficient
+ * message processing without interrupting other operations.
+ *
+ * @param queueName The name of the queue where messages will be sent
+ * @param secondsToWait The number of seconds to wait before sending messages
+ * @param numMessages The number of messages to send
+ * @param visibilityTimeout The duration in seconds that messages remain hidden after being received
+ * @return A task that can be executed to send the messages
+ */
+ public static Runnable sendAMessageAsync(String queueName, Long secondsToWait, Integer numMessages, Long visibilityTimeout) {
+ return () -> {
+ try {
+ Thread.sleep(Duration.ofSeconds(secondsToWait).toMillis());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ }
+ try {
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+ try (SQSConnection connection = connectionFactory.createConnection()) {
+ ensureQueueExists(connection, queueName, visibilityTimeout);
+ Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+ for (int i = 1; i <= numMessages; i++) {
+ MessageProducer producer = session.createProducer(session.createQueue(queueName));
+ producer.send(session.createTextMessage("Hello World " + i + "!"));
+ }
+ }
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ throw new RuntimeException(e);
+ }
+ };
+ }
+}
diff --git a/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/basic/JmsSqsSyncFifo.java b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/basic/JmsSqsSyncFifo.java
new file mode 100644
index 00000000000..d38d26d69e3
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/basic/JmsSqsSyncFifo.java
@@ -0,0 +1,102 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.basic;
+
+import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper;
+import com.amazon.sqs.javamessaging.ProviderConfiguration;
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.amazon.sqs.javamessaging.SQSConnectionFactory;
+import jakarta.jms.JMSException;
+import jakarta.jms.Message;
+import jakarta.jms.MessageConsumer;
+import jakarta.jms.MessageProducer;
+import jakarta.jms.Queue;
+import jakarta.jms.Session;
+import jakarta.jms.TextMessage;
+import org.slf4j.Logger;
+import software.amazon.awssdk.services.sqs.SqsClient;
+import software.amazon.awssdk.services.sqs.model.CreateQueueRequest;
+import software.amazon.awssdk.services.sqs.model.QueueAttributeName;
+
+import java.util.Map;
+import java.util.UUID;
+
+public class JmsSqsSyncFifo {
+ private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(JmsSqsSyncFifo.class);
+ private static final String QUEUE_NAME = "MyQueue-" + UUID.randomUUID() + ".fifo";
+
+ public static void main(String[] args) {
+ // Create a new connection factory with all defaults (credentials and region) set automatically.
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+ try {
+ // Create the connection.
+ SQSConnection connection = connectionFactory.createConnection();
+ // snippet-start:[sqs-jms.java2.jms-basics.create-fifo-queue]
+ // Get the wrapped client.
+ AmazonSQSMessagingClientWrapper client = connection.getWrappedAmazonSQSClient();
+ // Create an Amazon SQS FIFO queue, if it doesn't already exist. FIFO queue names must end in '.fifo'.
+ if (!client.queueExists(QUEUE_NAME)) {
+ Map attributes2 = Map.of(
+ QueueAttributeName.FIFO_QUEUE, "true",
+ QueueAttributeName.CONTENT_BASED_DEDUPLICATION, "true"
+ );
+ client.createQueue(CreateQueueRequest.builder()
+ .queueName(QUEUE_NAME)
+ .attributes(attributes2)
+ .build());
+ }
+ // snippet-end:[sqs-jms.java2.jms-basics.create-fifo-queue]
+
+ // Create a non-transacted session in AUTO_ACKNOWLEDGE mode.
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ // Create a queue identity and specify the queue name to the session.
+ Queue queue = session.createQueue(QUEUE_NAME);
+ // Create a producer for the queue.
+ MessageProducer producer = session.createProducer(queue);
+ // snippet-start:[sqs-jms.java2.jms-basics.send-text-message-fifo]
+ // Create a text message.
+ TextMessage message = session.createTextMessage("Hello World!");
+ // Set the message group ID.
+ message.setStringProperty("JMSXGroupID", "Default");
+
+ // You can also set a custom message deduplication ID. For example,
+ // `message.setStringProperty("JMS_SQS_DeduplicationId", "hello");`
+ // We don't need it for this example because content-based deduplication is enabled for the queue.
+
+ // Send the message.
+ producer.send(message);
+ LOGGER.info("JMS Message {}", message.getJMSMessageID());
+ LOGGER.info("JMS Message Sequence Number {}", message.getStringProperty("JMS_SQS_SequenceNumber"));
+ // snippet-end:[sqs-jms.java2.jms-basics.send-text-message-fifo]
+
+ // Create a consumer for the queue.
+ MessageConsumer consumer = session.createConsumer(queue);
+ // Start receiving incoming messages.
+ connection.start();
+ // snippet-start:[sqs-jms.java2.jms-basics.receive-msg-fifo-sync]
+ // Receive a message from the queue and wait up to 1 second.
+ Message receivedMessage = consumer.receive(1000);
+ // Cast the received message as a 'TextMessage' and display the text.
+ if (receivedMessage != null) {
+ LOGGER.info("Received: {}", ((TextMessage) receivedMessage).getText());
+ LOGGER.info("Group id: {}", receivedMessage.getStringProperty("JMSXGroupID"));
+ LOGGER.info("Message deduplication id: {}", receivedMessage.getStringProperty("JMS_SQS_DeduplicationId"));
+ LOGGER.info("Message sequence number: {}", receivedMessage.getStringProperty("JMS_SQS_SequenceNumber"));
+ }
+ // snippet-end:[sqs-jms.java2.jms-basics.receive-msg-fifo-sync]
+ SqsClient sqsClient = connection.getWrappedAmazonSQSClient().getAmazonSQSClient();
+ String queueUrl = connection.getWrappedAmazonSQSClient().getQueueUrl(QUEUE_NAME).queueUrl();
+ // Close the connection (and the session).
+ connection.close();
+ if (queueUrl != null){
+ sqsClient.deleteQueue(b -> b.queueUrl(queueUrl));
+ }
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/basic/JmsSqsSyncStandard.java b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/basic/JmsSqsSyncStandard.java
new file mode 100644
index 00000000000..63cf28c767c
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/basic/JmsSqsSyncStandard.java
@@ -0,0 +1,250 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.basic;
+
+import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper;
+import com.amazon.sqs.javamessaging.ProviderConfiguration;
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.amazon.sqs.javamessaging.SQSConnectionFactory;
+import com.amazon.sqs.javamessaging.SQSSession;
+import jakarta.jms.JMSException;
+import jakarta.jms.Message;
+import jakarta.jms.MessageConsumer;
+import jakarta.jms.MessageProducer;
+import jakarta.jms.Queue;
+import jakarta.jms.Session;
+import jakarta.jms.TextMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+
+import java.util.UUID;
+
+public class JmsSqsSyncStandard {
+ private static final Logger LOGGER = LoggerFactory.getLogger(JmsSqsSyncStandard.class);
+ private static final String QUEUE_NAME = "MyQueue" + UUID.randomUUID();
+ private static int ACKNOWLEDGE_MODE;
+ private static String RECEIVE_MODE;
+
+
+ /** This code example helps you get started using the SQS JMS client. Learn how to use the Java Message Service (JMS)
+ * with Amazon SQS. Create connections, send and receive messages, and implement asynchronous message handling.
+ *
+ * @param args Provide'-acknowledge-mode [ack-mode]' and '-receive-mode [receive-mode]' as program arguments.
+ * Valid values for [ack-mode] are 'auto', 'client' and 'unordered'. Values for [receive-mode] are 'sync' and 'async'.
+ * Example: -acknowledge-mode unordered -receive-mode sync
+ * Example: -acknowledge-mode client -receive-mode async
+ * If you don't provide program arguments, the defaults are `-acknowledge-mode unordered -receive-mode sync`.
+ */
+ public static void main(String[] args) {
+ parseProgramArgs(args);
+ // snippet-start:[sqs-jms.java2.jms-basics.create-conn-factory]
+ // Create a new connection factory with all defaults (credentials and region) set automatically.
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+ // snippet-end:[sqs-jms.java2.jms-basics.create-conn-factory]
+ try {
+ // snippet-start:[sqs-jms.java2.jms-basics.create-conn]
+ // Create the connection.
+ SQSConnection connection = connectionFactory.createConnection();
+ // snippet-end:[sqs-jms.java2.jms-basics.create-conn]
+
+ // snippet-start:[sqs-jms.java2.jms-basics.create-std-queue]
+ // Get the wrapped client.
+ AmazonSQSMessagingClientWrapper client = connection.getWrappedAmazonSQSClient();
+ // Create an SQS queue named 'MyQueue', if it doesn't already exist.
+ if (!client.queueExists(QUEUE_NAME)) {
+ client.createQueue(QUEUE_NAME);
+ }
+ // snippet-end:[sqs-jms.java2.jms-basics.create-std-queue]
+
+
+ Session session;
+ if (RECEIVE_MODE.equals("sync")) {
+ session = switch (ACKNOWLEDGE_MODE) {
+ case Session.AUTO_ACKNOWLEDGE -> createAutoAcknowledgeSession(connection);
+ case Session.CLIENT_ACKNOWLEDGE -> createClientAcknowledgeSession(connection);
+ case SQSSession.UNORDERED_ACKNOWLEDGE -> createUnorderedAcknowledgeSession(connection);
+ default -> throw new IllegalStateException("Unexpected value: " + ACKNOWLEDGE_MODE);
+ };
+ } else {
+ session = createAutoAcknowledgeSession(connection);
+ }
+ // snippet-start:[sqs-jms.java2.jms-basics.create-send-setup]
+ // Create a queue identity and specify the queue name to the session.
+ Queue queue = session.createQueue(QUEUE_NAME);
+ // Create a producer for queue.
+ MessageProducer producer = session.createProducer(queue);
+ // snippet-end:[sqs-jms.java2.jms-basics.create-send-setup]
+
+ // snippet-start:[sqs-jms.java2.jms-basics.send-text-message-std]
+ // Create the text message.
+ TextMessage message = session.createTextMessage("Hello World!");
+ // Send the message.
+ producer.send(message);
+ LOGGER.info("JMS Message {}", message.getJMSMessageID());
+ // snippet-end:[sqs-jms.java2.jms-basics.send-text-message-std]
+
+ switch (RECEIVE_MODE) {
+ case "sync" -> {
+ switch (ACKNOWLEDGE_MODE) {
+ case Session.AUTO_ACKNOWLEDGE -> receiveMessageAutoAckSync(connection, session, queue);
+ case Session.CLIENT_ACKNOWLEDGE -> receiveMessageExplicitAckSync(connection, session, queue);
+ case SQSSession.UNORDERED_ACKNOWLEDGE -> receiveMessageExplicitAckSync(connection, session, queue);
+ }
+ }
+ case "async" -> receiveMessageAutoAckAsync(connection, session, queue);
+ }
+ SqsClient sqsClient = connection.getWrappedAmazonSQSClient().getAmazonSQSClient();
+ String queueUrl = connection.getWrappedAmazonSQSClient().getQueueUrl(QUEUE_NAME).queueUrl();
+ if (queueUrl != null){
+ sqsClient.deleteQueue(b -> b.queueUrl(queueUrl));
+ }
+ // snippet-start:[sqs-jms.java2.jms-basics.close-conn]
+ // Close the connection (and the session).
+ connection.close();
+ // snippet-end:[sqs-jms.java2.jms-basics.close-conn]
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static Session createAutoAcknowledgeSession(SQSConnection connection) {
+ try {
+ // snippet-start:[sqs-jms.java2.jms-basics.create-session-auto-ack]
+ // Create the non-transacted session with AUTO_ACKNOWLEDGE mode.
+ return connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ // snippet-end:[sqs-jms.java2.jms-basics.create-session-auto-ack]
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static Session createClientAcknowledgeSession(SQSConnection connection) {
+ try {
+ // snippet-start:[sqs-jms.java2.jms-basics.create-session-client-ack]
+ // Create the non-transacted session with CLIENT_ACKNOWLEDGE mode.
+ return connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+ // snippet-end:[sqs-jms.java2.jms-basics.create-session-client-ack]
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static Session createUnorderedAcknowledgeSession(SQSConnection connection) {
+ try {
+ // snippet-start:[sqs-jms.java2.jms-basics.create-session-unordered-ack]
+ // Create the non-transacted session with UNORDERED_ACKNOWLEDGE mode.
+ return connection.createSession(false, SQSSession.UNORDERED_ACKNOWLEDGE);
+ // snippet-end:[sqs-jms.java2.jms-basics.create-session-unordered-ack]
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static void receiveMessageAutoAckSync(SQSConnection connection, Session session, Queue queue) {
+ try {
+ // snippet-start:[sqs-jms.java2.jms-basics.receive-setup-std-sync]
+ // Create a consumer for the queue.
+ MessageConsumer consumer = session.createConsumer(queue);
+ // Start receiving incoming messages.
+ connection.start();
+ // snippet-end:[sqs-jms.java2.jms-basics.receive-setup-std-sync]
+ // snippet-start:[sqs-jms.java2.jms-basics.receive-msg-std-sync]
+ // Receive a message from the queue and wait up to 1 second.
+ Message receivedMessage = consumer.receive(1000);
+
+ // Cast the received message as a 'TextMessage' and display the text.
+ if (receivedMessage != null) {
+ LOGGER.info("Received: {}", ((TextMessage) receivedMessage).getText());
+ }
+ // snippet-end:[sqs-jms.java2.jms-basics.receive-msg-std-sync]
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static void receiveMessageExplicitAckSync(SQSConnection connection, Session session, Queue queue) {
+ try {
+ // Create a consumer for the queue.
+ MessageConsumer consumer = session.createConsumer(queue);
+ // Start receiving incoming messages.
+ connection.start();
+ // Receive a message from the queue and wait up to 1 second.
+ Message receivedMessage = consumer.receive(1000);
+ // snippet-start:[sqs-jms.java2.jms-basics.receive-msg-client-ack]
+ // Cast the received message as a 'TextMessage' and display the text.
+ if (receivedMessage != null) {
+ LOGGER.info("Received: {}", ((TextMessage) receivedMessage).getText());
+ receivedMessage.acknowledge();
+ LOGGER.info("Acknowledged: {}", receivedMessage.getJMSMessageID());
+ }
+ // snippet-end:[sqs-jms.java2.jms-basics.receive-msg-client-ack]
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static void receiveMessageAutoAckAsync(SQSConnection connection, Session session, Queue queue) {
+ // snippet-start:[sqs-jms.java2.jms-basics.receive-async]
+ try {
+ // Create a consumer for the queue.
+ MessageConsumer consumer = session.createConsumer(queue);
+ // Provide an implementation of the MessageListener interface, which has a single 'onMessage' method.
+ // We use a lambda expression for the implementation.
+ consumer.setMessageListener(message -> {
+ try {
+ // Cast the received message as TextMessage and print the text to screen.
+ LOGGER.info("Received: {}", ((TextMessage) message).getText());
+ } catch (JMSException e) {
+ LOGGER.error("Error processing message: {}", e.getMessage());
+ }
+ });
+ // Start receiving incoming messages.
+ connection.start();
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ // snippet-end:[sqs-jms.java2.jms-basics.receive-async]
+ }
+
+ static void parseProgramArgs(String[] args) {
+ for (int i = 0; i < args.length; i++) {
+ switch (args[i]) {
+ case "-acknowledge-mode":
+ if (i + 1 < args.length) {
+ switch (args[i + 1]) {
+ case "auto" -> ACKNOWLEDGE_MODE = Session.AUTO_ACKNOWLEDGE;
+ case "client" -> ACKNOWLEDGE_MODE = Session.CLIENT_ACKNOWLEDGE;
+ case "unordered" -> ACKNOWLEDGE_MODE = SQSSession.UNORDERED_ACKNOWLEDGE;
+ }
+ i++;
+ }
+ break;
+ case "-receive-mode":
+ if (i + 1 < args.length) {
+ switch (args[i + 1]){
+ case "sync" -> RECEIVE_MODE = "sync";
+ case "async" -> RECEIVE_MODE = "async";
+ }
+ i++;
+ }
+ break;
+ }
+ }
+ if (ACKNOWLEDGE_MODE == 0) {
+ ACKNOWLEDGE_MODE = Session.AUTO_ACKNOWLEDGE;
+ }
+ if (RECEIVE_MODE == null) {
+ RECEIVE_MODE = "sync";
+ }
+ }
+}
diff --git a/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/spring/SpringExample.java b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/spring/SpringExample.java
new file mode 100644
index 00000000000..8048c89ff84
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/spring/SpringExample.java
@@ -0,0 +1,117 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+// snippet-start:[sqs-jms.java2.spring]
+package com.example.sqs.jms.spring;
+
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.support.FileSystemXmlApplicationContext;
+
+import java.io.File;
+import java.net.URL;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Demonstrates how to send and receive messages using the Amazon SQS Java Messaging Library
+ * with Spring Framework integration. This example connects to a standard Amazon SQS message
+ * queue using Spring's dependency injection to configure the connection and messaging components.
+ * The application uses the JMS (Java Message Service) API to handle message operations.
+ */
+public class SpringExample {
+ private static final Integer POLLING_SECONDS = 15;
+ private static final String SPRING_XML_CONFIG_FILE = "SpringExampleConfiguration.xml.txt";
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringExample.class);
+
+ /**
+ * Demonstrates sending and receiving messages through a standard Amazon SQS message queue
+ * using Spring Framework configuration. This method loads connection settings from an XML file,
+ * establishes a messaging session using the Amazon SQS Java Messaging Library, and processes
+ * messages using JMS (Java Message Service) operations. If the queue doesn't exist, it will
+ * be created automatically.
+ *
+ * @param args Command line arguments (not used)
+ */
+ public static void main(String[] args) {
+
+ URL resource = SpringExample.class.getClassLoader().getResource(SPRING_XML_CONFIG_FILE);
+ File springFile = new File(resource.getFile());
+ if (!springFile.exists() || !springFile.canRead()) {
+ LOGGER.error("File " + SPRING_XML_CONFIG_FILE + " doesn't exist or isn't readable.");
+ System.exit(1);
+ }
+
+ try (FileSystemXmlApplicationContext context =
+ new FileSystemXmlApplicationContext("file://" + springFile.getAbsolutePath())) {
+
+ Connection connection;
+ try {
+ connection = context.getBean(Connection.class);
+ } catch (NoSuchBeanDefinitionException e) {
+ LOGGER.error("Can't find the JMS connection to use: " + e.getMessage(), e);
+ System.exit(2);
+ return;
+ }
+
+ String queueName;
+ try {
+ queueName = context.getBean("queueName", String.class);
+ } catch (NoSuchBeanDefinitionException e) {
+ LOGGER.error("Can't find the name of the queue to use: " + e.getMessage(), e);
+ System.exit(3);
+ return;
+ }
+ try {
+ if (connection instanceof SQSConnection) {
+ SqsJmsExampleUtils.ensureQueueExists((SQSConnection) connection, queueName, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT);
+ }
+ // Create the JMS session.
+ Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ SqsJmsExampleUtils.sendTextMessage(session, queueName);
+ MessageConsumer consumer = session.createConsumer(session.createQueue(queueName));
+
+ receiveMessages(consumer);
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ throw new RuntimeException(e);
+ }
+ } // Spring context autocloses. Managed Spring beans that implement AutoClosable, such as the
+ // 'connection' bean, are also closed.
+ LOGGER.info("Context closed");
+ }
+
+ /**
+ * Continuously checks for and processes messages from a standard Amazon SQS message queue
+ * using the Amazon SQS Java Messaging Library underlying the JMS API. This method waits for incoming messages,
+ * processes them when they arrive, and acknowledges their receipt using JMS (Java Message
+ * Service) operations. The method will stop checking for messages after 15 seconds of
+ * inactivity.
+ *
+ * @param consumer The JMS message consumer used to receive messages from the queue
+ */
+ private static void receiveMessages(MessageConsumer consumer) {
+ try {
+ while (true) {
+ LOGGER.info("Waiting for messages...");
+ // Wait 15 seconds for a message.
+ Message message = consumer.receive(TimeUnit.SECONDS.toMillis(POLLING_SECONDS));
+ if (message == null) {
+ LOGGER.info("Shutting down after {} seconds of silence.", POLLING_SECONDS);
+ break;
+ }
+ SqsJmsExampleUtils.handleMessage(message);
+ message.acknowledge();
+ LOGGER.info("Message acknowledged.");
+ }
+ } catch (JMSException e) {
+ LOGGER.error("Error receiving from SQS.", e);
+ }
+ }
+}
+// snippet-end:[sqs-jms.java2.spring]
+
diff --git a/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/AsyncMessageReceiver.java b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/AsyncMessageReceiver.java
new file mode 100644
index 00000000000..79ff08b068a
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/AsyncMessageReceiver.java
@@ -0,0 +1,97 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import com.amazon.sqs.javamessaging.ProviderConfiguration;
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.amazon.sqs.javamessaging.SQSConnectionFactory;
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.JMSException;
+import jakarta.jms.MessageConsumer;
+import jakarta.jms.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+
+import java.util.UUID;
+
+/**
+ * This class demonstrates non-blocking message processing with a standard Amazon SQS queue
+ * using the Amazon SQS Java Messaging Library. It shows how to receive and process messages
+ * automatically as they arrive using JMS (Java Message Service) event listeners, allowing
+ * the application to perform other tasks while waiting for messages.
+ */
+public class AsyncMessageReceiver {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AsyncMessageReceiver.class);
+ public static final String QUEUE_NAME = "SQSJMSClientExampleQueue" + UUID.randomUUID();
+
+ public static void main(String[] args){
+ try {
+ new Thread(SqsJmsExampleUtils.sendAMessageAsync(QUEUE_NAME, 3L, 5, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT)).start();
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ try {
+ doReceiveMessageAsync();
+ SqsJmsExampleUtils.cleanUpExample(QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT );
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+
+ // snippet-start:[sqs-jms.java2.receive-message-async]
+ /**
+ * This method sets up automatic message handling for a standard Amazon SQS queue using the
+ * Amazon SQS Java Messaging Library. It creates a listener that processes messages as soon
+ * as they arrive using JMS (Java Message Service), runs for 5 seconds, then cleans up all
+ * messaging resources.
+ *
+ * @throws JMSException If there is a problem connecting to or receiving messages from the queue
+ */
+ public static void doReceiveMessageAsync() throws JMSException {
+ // Create a connection factory.
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+
+ // Create a connection.
+ try (SQSConnection connection = connectionFactory.createConnection() ) {
+
+ // Create the queue if needed.
+ SqsJmsExampleUtils.ensureQueueExists(connection, QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT);
+
+ // Create a session.
+ Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ try {
+ // Create a consumer for the queue.
+ MessageConsumer consumer = session.createConsumer(session.createQueue(QUEUE_NAME));
+ // Provide an implementation of the MessageListener interface, which has a single 'onMessage' method.
+ // We use a lambda expression for the implementation.
+ consumer.setMessageListener(message -> {
+ try {
+ SqsJmsExampleUtils.handleMessage(message);
+ message.acknowledge();
+ } catch (JMSException e) {
+ LOGGER.error("Error processing message: {}", e.getMessage());
+ }
+ });
+ // Start receiving incoming messages.
+ connection.start();
+ LOGGER.info("Waiting for messages...");
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ } // The connection closes automatically. This also closes the session.
+ LOGGER.info( "Connection closed" );
+ }
+ // snippet-end:[sqs-jms.java2.receive-message-async]
+
+}
diff --git a/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/SyncMessageReceiver.java b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/SyncMessageReceiver.java
new file mode 100644
index 00000000000..6cc4fb95ff8
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/SyncMessageReceiver.java
@@ -0,0 +1,106 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import com.amazon.sqs.javamessaging.ProviderConfiguration;
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.amazon.sqs.javamessaging.SQSConnectionFactory;
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.JMSException;
+import jakarta.jms.Message;
+import jakarta.jms.MessageConsumer;
+import jakarta.jms.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+
+import java.time.Duration;
+import java.util.UUID;
+
+/**
+ * This class demonstrates synchronous message processing with a standard Amazon SQS queue
+ * using the Amazon SQS Java Messaging Library. It shows how to receive messages from the queue
+ * using standard JMS (Java Message Service) interfaces, processing each message completely
+ * before moving to the next one.
+ */
+public class SyncMessageReceiver {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SyncMessageReceiver.class);
+ public static final String QUEUE_NAME = "SQSJMSClientExampleQueue" + UUID.randomUUID();
+
+ public static void main(String[] args) {
+ try {
+ new Thread(SqsJmsExampleUtils.sendAMessageAsync(QUEUE_NAME, 10L, 1, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT)).start();
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ try {
+ doReceiveMessageSync();
+ SqsJmsExampleUtils.cleanUpExample(QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT);
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+
+ // snippet-start:[sqs-jms.java2.receive-message-sync]
+ /**
+ * This method receives messages from a standard Amazon SQS queue using the Amazon SQS Java
+ * Messaging Library. It creates a connection to the queue using JMS (Java Message Service),
+ * waits for messages to arrive, and processes them one at a time. The method handles all
+ * necessary setup and cleanup of messaging resources.
+ *
+ * @throws JMSException If there is a problem connecting to or receiving messages from the queue
+ */
+ public static void doReceiveMessageSync() throws JMSException {
+ // Create a connection factory.
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+
+ // Create a connection.
+ try (SQSConnection connection = connectionFactory.createConnection() ) {
+
+ // Create the queue if needed.
+ SqsJmsExampleUtils.ensureQueueExists(connection, QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT);
+
+ // Create a session.
+ Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+ MessageConsumer consumer = session.createConsumer(session.createQueue(QUEUE_NAME));
+
+ connection.start();
+
+ receiveMessages(consumer);
+ } // The connection closes automatically. This also closes the session.
+ LOGGER.info("Connection closed");
+ }
+
+ /**
+ * This method continuously checks for new messages from a standard Amazon SQS queue using
+ * the Amazon SQS Java Messaging Library. It waits up to 20 seconds for each message, processes
+ * it using JMS (Java Message Service), and confirms receipt. The method stops checking for
+ * messages after 20 seconds of no activity.
+ *
+ * @param consumer The JMS message consumer that receives messages from the queue
+ */
+ private static void receiveMessages(MessageConsumer consumer) {
+ try {
+ while (true) {
+ LOGGER.info("Waiting for messages...");
+ // Wait 1 minute for a message
+ Message message = consumer.receive(Duration.ofSeconds(20).toMillis());
+ if (message == null) {
+ LOGGER.info("Shutting down after 20 seconds of silence.");
+ break;
+ }
+ SqsJmsExampleUtils.handleMessage(message);
+ message.acknowledge();
+ LOGGER.info("Acknowledged message {}", message.getJMSMessageID());
+ }
+ } catch (JMSException e) {
+ LOGGER.error("Error receiving from SQS: {}", e.getMessage(), e);
+ }
+ }
+ // snippet-end:[sqs-jms.java2.receive-message-sync]
+
+}
diff --git a/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverClientAcknowledge.java b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverClientAcknowledge.java
new file mode 100644
index 00000000000..5695c8bf709
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverClientAcknowledge.java
@@ -0,0 +1,144 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import com.amazon.sqs.javamessaging.ProviderConfiguration;
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.amazon.sqs.javamessaging.SQSConnectionFactory;
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+
+import java.time.Duration;
+import java.util.UUID;
+
+/**
+ * This class demonstrates manual message acknowledgment with a standard Amazon SQS queue
+ * using the Amazon SQS Java Messaging Library. It shows how to receive messages synchronously
+ * and explicitly confirm their processing using JMS (Java Message Service) client
+ * acknowledgment mode, giving the application full control over message completion.
+ */
+public class SyncMessageReceiverClientAcknowledge {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SyncMessageReceiverClientAcknowledge.class);
+ public static final String QUEUE_NAME = "SQSJMSClientExampleQueue" + UUID.randomUUID();
+
+ // Visibility time-out for the queue.
+ private static final Long TIME_OUT_SECONDS = 5L;
+ private static final Long TIME_OUT_MILLIS = Duration.ofSeconds(TIME_OUT_SECONDS).toMillis();
+
+ public static void main(String[] args) {
+ try {
+ doReceiveMessagesSyncClientAcknowledge();
+ SqsJmsExampleUtils.cleanUpExample(QUEUE_NAME, TIME_OUT_SECONDS);
+ } catch (JMSException e) {
+ LOGGER.error("JMS Exception occurred", e);
+ }
+ }
+
+ // snippet-start:[sqs-jms.java2.receive-message-sync-client-ack]
+ /**
+ * This method demonstrates how message acknowledgment affects message processing in a standard
+ * Amazon SQS queue using the Amazon SQS Java Messaging Library. It sends messages to the queue,
+ * then shows how JMS (Java Message Service) client acknowledgment mode handles both explicit
+ * and implicit message confirmations, including how acknowledging one message can automatically
+ * acknowledge previous messages.
+ *
+ * @throws JMSException If there is a problem with the messaging operations
+ */
+ public static void doReceiveMessagesSyncClientAcknowledge() throws JMSException {
+ // Create a connection factory.
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+
+ // Create the connection in a try-with-resources statement so that it's closed automatically.
+ try (SQSConnection connection = connectionFactory.createConnection() ) {
+
+ // Create the queue if needed.
+ SqsJmsExampleUtils.ensureQueueExists(connection, QUEUE_NAME, TIME_OUT_SECONDS);
+
+ // Create a session with client acknowledge mode.
+ Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ // Create a producer and consumer.
+ MessageProducer producer = session.createProducer(session.createQueue(QUEUE_NAME));
+ MessageConsumer consumer = session.createConsumer(session.createQueue(QUEUE_NAME));
+
+ // Open the connection.
+ connection.start();
+
+ // Send two text messages.
+ sendMessage(producer, session, "Message 1");
+ sendMessage(producer, session, "Message 2");
+
+ // Receive a message and don't acknowledge it.
+ receiveMessage(consumer, false);
+
+ // Receive another message and acknowledge it.
+ receiveMessage(consumer, true);
+
+ // Wait for the visibility time out, so that unacknowledged messages reappear in the queue,
+ LOGGER.info("Waiting for visibility timeout...");
+ try {
+ Thread.sleep(TIME_OUT_MILLIS);
+ } catch (InterruptedException e) {
+ LOGGER.error("Interrupted while waiting for visibility timeout", e);
+ Thread.currentThread().interrupt();
+ throw new RuntimeException("Processing interrupted", e);
+ }
+
+ /* We will attempt to receive another message, but none will be available. This is because in
+ CLIENT_ACKNOWLEDGE mode, when we acknowledged the second message, all previous messages were
+ automatically acknowledged as well. Therefore, although we never directly acknowledged the first
+ message, it was implicitly acknowledged when we confirmed the second one. */
+ receiveMessage(consumer, true);
+ } // The connection closes automatically. This also closes the session.
+ LOGGER.info("Connection closed.");
+
+ }
+
+
+ /**
+ * Sends a text message using the specified JMS MessageProducer and Session.
+ *
+ * @param producer The JMS MessageProducer used to send the message
+ * @param session The JMS Session used to create the text message
+ * @param messageText The text content to be sent in the message
+ * @throws JMSException If there is an error creating or sending the message
+ */
+ private static void sendMessage(MessageProducer producer, Session session, String messageText) throws JMSException {
+ // Create a text message and send it.
+ producer.send(session.createTextMessage(messageText));
+ }
+
+ /**
+ * Receives and processes a message from a JMS queue using the specified consumer.
+ * The method waits for a message until the configured timeout period is reached.
+ * If a message is received, it is logged and optionally acknowledged based on the
+ * acknowledge parameter.
+ *
+ * @param consumer The JMS MessageConsumer used to receive messages from the queue
+ * @param acknowledge Boolean flag indicating whether to acknowledge the message.
+ * If true, the message will be acknowledged after processing
+ * @throws JMSException If there is an error receiving, processing, or acknowledging the message
+ */
+ private static void receiveMessage(MessageConsumer consumer, boolean acknowledge) throws JMSException {
+ // Receive a message.
+ Message message = consumer.receive(TIME_OUT_MILLIS);
+
+ if (message == null) {
+ LOGGER.info("Queue is empty!");
+ } else {
+ // Since this queue has only text messages, cast the message object and print the text.
+ LOGGER.info("Received: {} Acknowledged: {}", ((TextMessage) message).getText(), acknowledge);
+
+ // Acknowledge the message if asked.
+ if (acknowledge) message.acknowledge();
+ }
+ }
+ // snippet-end:[sqs-jms.java2.receive-message-sync-client-ack]
+}
diff --git a/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverUnorderedAcknowledge.java b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverUnorderedAcknowledge.java
new file mode 100644
index 00000000000..3ee743b3d08
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverUnorderedAcknowledge.java
@@ -0,0 +1,140 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import com.amazon.sqs.javamessaging.ProviderConfiguration;
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.amazon.sqs.javamessaging.SQSConnectionFactory;
+import com.amazon.sqs.javamessaging.SQSSession;
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+
+import java.time.Duration;
+import java.util.UUID;
+
+/**
+ * This class demonstrates independent message acknowledgment with a standard Amazon SQS queue
+ * using the Amazon SQS Java Messaging Library. It shows how to process messages using JMS
+ * (Java Message Service) with unordered acknowledgment mode, where each message must be
+ * confirmed separately regardless of when it was received, providing fine-grained control
+ * over message completion.
+ */
+public class SyncMessageReceiverUnorderedAcknowledge {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SyncMessageReceiverUnorderedAcknowledge.class);
+ public static final String QUEUE_NAME = "SQSJMSClientExampleQueue" + UUID.randomUUID();
+
+ // Visibility time-out for the queue.
+ private static final Long TIME_OUT_SECONDS = 5L;
+ private static final Long TIME_OUT_MILLIS = Duration.ofSeconds(TIME_OUT_SECONDS).toMillis();
+
+ public static void main(String[] args) {
+ try {
+ doReceiveMessagesUnorderedAcknowledge();
+ SqsJmsExampleUtils.cleanUpExample(QUEUE_NAME, TIME_OUT_SECONDS);
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+
+ // snippet-start:[sqs-jms.java2.receive-message-sync-unordered-ack]
+ /**
+ * Demonstrates message acknowledgment behavior in UNORDERED_ACKNOWLEDGE mode with Amazon SQS JMS.
+ * In this mode, each message must be explicitly acknowledged regardless of receive order.
+ * Unacknowledged messages return to the queue after the visibility timeout expires,
+ * unlike CLIENT_ACKNOWLEDGE mode where acknowledging one message acknowledges all previous messages.
+ *
+ * @throws JMSException If a JMS-related error occurs during message operations
+ */
+ public static void doReceiveMessagesUnorderedAcknowledge() throws JMSException {
+ // Create a connection factory.
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+
+ // Create the connection in a try-with-resources statement so that it's closed automatically.
+ try( SQSConnection connection = connectionFactory.createConnection() ) {
+
+ // Create the queue if needed.
+ SqsJmsExampleUtils.ensureQueueExists(connection, QUEUE_NAME, TIME_OUT_SECONDS);
+
+ // Create a session with unordered acknowledge mode.
+ Session session = connection.createSession(false, SQSSession.UNORDERED_ACKNOWLEDGE);
+
+ // Create the producer and consumer.
+ MessageProducer producer = session.createProducer(session.createQueue(QUEUE_NAME));
+ MessageConsumer consumer = session.createConsumer(session.createQueue(QUEUE_NAME));
+
+ // Open a connection.
+ connection.start();
+
+ // Send two text messages.
+ sendMessage(producer, session, "Message 1");
+ sendMessage(producer, session, "Message 2");
+
+ // Receive a message and don't acknowledge it.
+ receiveMessage(consumer, false);
+
+ // Receive another message and acknowledge it.
+ receiveMessage(consumer, true);
+
+ // Wait for the visibility time out, so that unacknowledged messages reappear in the queue.
+ LOGGER.info("Waiting for visibility timeout...");
+ try {
+ Thread.sleep(TIME_OUT_MILLIS);
+ } catch (InterruptedException e) {
+ LOGGER.error("Interrupted while waiting for visibility timeout", e);
+ Thread.currentThread().interrupt();
+ throw new RuntimeException("Processing interrupted", e);
+ }
+
+ /* We will attempt to receive another message, and we'll get the first message again. This occurs
+ because in UNORDERED_ACKNOWLEDGE mode, each message requires its own separate acknowledgment.
+ Since we only acknowledged the second message, the first message remains in the queue for
+ redelivery. */
+ receiveMessage(consumer, true);
+
+ LOGGER.info("Connection closed.");
+ } // The connection closes automatically. This also closes the session.
+ }
+
+ /**
+ * Sends a text message to an Amazon SQS queue using JMS.
+ *
+ * @param producer The JMS MessageProducer for the queue
+ * @param session The JMS Session for message creation
+ * @param messageText The message content
+ * @throws JMSException If message creation or sending fails
+ */
+ private static void sendMessage(MessageProducer producer, Session session, String messageText) throws JMSException {
+ // Create a text message and send it.
+ producer.send(session.createTextMessage(messageText));
+ }
+ /**
+ * Synchronously receives a message from an Amazon SQS queue using the JMS API
+ * with an acknowledgment parameter.
+ *
+ * @param consumer The JMS MessageConsumer for the queue
+ * @param acknowledge If true, acknowledges the message after receipt
+ * @throws JMSException If message reception or acknowledgment fails
+ */
+ private static void receiveMessage(MessageConsumer consumer, boolean acknowledge) throws JMSException {
+ // Receive a message.
+ Message message = consumer.receive(TIME_OUT_MILLIS);
+
+ if (message == null) {
+ LOGGER.info("Queue is empty!");
+ } else {
+ // Since this queue has only text messages, cast the message object and print the text.
+ LOGGER.info("Received: {} Acknowledged: {}", ((TextMessage) message).getText(), acknowledge);
+
+ // Acknowledge the message if asked.
+ if (acknowledge) message.acknowledge();
+ }
+ }
+ // snippet-end:[sqs-jms.java2.receive-message-sync-unordered-ack]
+}
diff --git a/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/TextMessageSender.java b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/TextMessageSender.java
new file mode 100644
index 00000000000..4cd89dc497a
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/TextMessageSender.java
@@ -0,0 +1,113 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import com.amazon.sqs.javamessaging.ProviderConfiguration;
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.amazon.sqs.javamessaging.SQSConnectionFactory;
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.JMSException;
+import jakarta.jms.MessageProducer;
+import jakarta.jms.Session;
+import jakarta.jms.TextMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+
+import java.io.BufferedReader;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.util.UUID;
+
+/**
+ * This class demonstrates how to send text-based messages to a standard Amazon SQS queue
+ * using the Amazon SQS Java Messaging Library. It provides an interactive way to compose
+ * and send messages through JMS (Java Message Service), allowing users to type messages
+ * that are then delivered to the queue.
+ */
+public class TextMessageSender {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TextMessageSender.class);
+ private static final String QUEUE_NAME = "SQSJMSClientExampleQueue" + UUID.randomUUID();
+
+ public static void main(String[] args) {
+ try {
+ doSendTextMessage();
+ } catch (JMSException e) {
+ LOGGER.error("Failed to send message: {}", e.getMessage(), e);
+ } finally {
+ try {
+ SqsJmsExampleUtils.cleanUpExample(QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT);
+ } catch (Exception e) {
+ LOGGER.error("Failed to cleanup resources: {}", e.getMessage(), e);
+ }
+ }
+ }
+
+ // snippet-start:[sqs-jms.java2.send-text-message]
+ /**
+ * This method establishes a connection to a standard Amazon SQS queue using the Amazon SQS
+ * Java Messaging Library and sends text messages to it. It uses JMS (Java Message Service) API
+ * with automatic acknowledgment mode to ensure reliable message delivery, and automatically
+ * manages all messaging resources.
+ *
+ * @throws JMSException If there is a problem connecting to or sending messages to the queue
+ */
+ public static void doSendTextMessage() throws JMSException {
+ // Create a connection factory.
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+
+ // Create the connection in a try-with-resources statement so that it's closed automatically.
+ try (SQSConnection connection = connectionFactory.createConnection()) {
+
+ // Create the queue if needed.
+ SqsJmsExampleUtils.ensureQueueExists(connection, QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT);
+
+ // Create a session that uses the JMS auto-acknowledge mode.
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer producer = session.createProducer(session.createQueue(QUEUE_NAME));
+
+ createAndSendMessages(session, producer);
+ } // The connection closes automatically. This also closes the session.
+ LOGGER.info("Connection closed");
+ }
+
+ /**
+ * This method reads text input from the keyboard and sends each line as a separate message
+ * to a standard Amazon SQS queue using the Amazon SQS Java Messaging Library. It continues
+ * to accept input until the user enters an empty line, using JMS (Java Message Service) API to
+ * handle the message delivery.
+ *
+ * @param session The JMS session used to create messages
+ * @param producer The JMS message producer used to send messages to the queue
+ */
+ private static void createAndSendMessages(Session session, MessageProducer producer) {
+ BufferedReader inputReader = new BufferedReader(
+ new InputStreamReader(System.in, Charset.defaultCharset()));
+
+ try {
+ String input;
+ while (true) {
+ LOGGER.info("Enter message to send (leave empty to exit): ");
+ input = inputReader.readLine();
+ if (input == null || input.isEmpty()) break;
+
+ TextMessage message = session.createTextMessage(input);
+ producer.send(message);
+ LOGGER.info("Send message {}", message.getJMSMessageID());
+ }
+ } catch (EOFException e) {
+ // Just return on EOF
+ } catch (IOException e) {
+ LOGGER.error("Failed reading input: {}", e.getMessage(), e);
+ } catch (JMSException e) {
+ LOGGER.error("Failed sending message: {}", e.getMessage(), e);
+ }
+ }
+ // snippet-end:[sqs-jms.java2.send-text-message]
+}
diff --git a/javav2/example_code/sqs-jms/src/main/resources/SpringExampleConfiguration.xml.txt b/javav2/example_code/sqs-jms/src/main/resources/SpringExampleConfiguration.xml.txt
new file mode 100644
index 00000000000..7d05abca765
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/resources/SpringExampleConfiguration.xml.txt
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/javav2/example_code/sqs-jms/src/main/resources/log4j2.xml b/javav2/example_code/sqs-jms/src/main/resources/log4j2.xml
new file mode 100644
index 00000000000..41b0f8963fc
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/main/resources/log4j2.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/basic/JmsSqsSyncStandardTest.java b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/basic/JmsSqsSyncStandardTest.java
new file mode 100644
index 00000000000..679453a26fb
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/basic/JmsSqsSyncStandardTest.java
@@ -0,0 +1,149 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.basic;
+
+import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper;
+import com.amazon.sqs.javamessaging.ProviderConfiguration;
+import com.amazon.sqs.javamessaging.SQSConnection;
+import com.amazon.sqs.javamessaging.SQSConnectionFactory;
+import jakarta.jms.JMSException;
+import jakarta.jms.Message;
+import jakarta.jms.MessageConsumer;
+import jakarta.jms.MessageProducer;
+import jakarta.jms.Queue;
+import jakarta.jms.Session;
+import jakarta.jms.TextMessage;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import software.amazon.awssdk.services.sqs.SqsClient;
+
+import java.util.UUID;
+
+class JmsSqsSyncStandardTest {
+ private final String QUEUE_NAME = "MyQueueTst" + UUID.randomUUID();
+ private SQSConnection connection;
+
+ @BeforeEach
+ void setUp() {
+ try {
+ SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
+ new ProviderConfiguration(),
+ SqsClient.create()
+ );
+ connection = connectionFactory.createConnection();
+ AmazonSQSMessagingClientWrapper client = connection.getWrappedAmazonSQSClient();
+ // Create an SQS queue named 'MyQueue', if it doesn't already exist.
+ if (!client.queueExists(QUEUE_NAME)) {
+ client.createQueue(QUEUE_NAME);
+ }
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ @AfterEach
+ void tearDown() {
+ try {
+ SqsClient sqsClient = connection.getWrappedAmazonSQSClient().getAmazonSQSClient();
+ String queueUrl = connection.getWrappedAmazonSQSClient().getQueueUrl(QUEUE_NAME).queueUrl();
+ connection.close();
+ if (queueUrl != null){
+ sqsClient.deleteQueue(b -> b.queueUrl(queueUrl));
+ }
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ void autoAckAsyncTest() {
+ try {
+ Session session = JmsSqsSyncStandard.createAutoAcknowledgeSession(connection);
+ Queue queue = session.createQueue(QUEUE_NAME);
+ MessageProducer producer = session.createProducer(queue);
+ TextMessage message = session.createTextMessage("Hello World!");
+ producer.send(message);
+ JmsSqsSyncStandard.receiveMessageAutoAckAsync(connection, session, queue);
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ MessageConsumer consumer = session.createConsumer(queue);
+ connection.start();
+ Message reReceivedMessage = consumer.receive(1000);
+ Assertions.assertNull(reReceivedMessage);
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ @Test
+ void autoAckSyncTest() {
+ try {
+ Session session = JmsSqsSyncStandard.createAutoAcknowledgeSession(connection);
+ Queue queue = session.createQueue(QUEUE_NAME);
+ MessageProducer producer = session.createProducer(queue);
+ TextMessage message = session.createTextMessage("Hello World!");
+ producer.send(message);
+ JmsSqsSyncStandard.receiveMessageAutoAckAsync(connection, session, queue);
+
+ MessageConsumer consumer = session.createConsumer(queue);
+ connection.start();
+ Message reReceivedMessage = consumer.receive(1000);
+ Assertions.assertNull(reReceivedMessage);
+
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ @Test
+ @Tag("IntegrationTest")
+ void clientAckSyncTest() {
+ try {
+ Session session = JmsSqsSyncStandard.createClientAcknowledgeSession(connection);
+ Queue queue = session.createQueue(QUEUE_NAME);
+ MessageProducer producer = session.createProducer(queue);
+ TextMessage message = session.createTextMessage("Hello World!");
+ producer.send(message);
+ JmsSqsSyncStandard.receiveMessageExplicitAckSync(connection, session, queue);
+
+ MessageConsumer consumer = session.createConsumer(queue);
+ connection.start();
+ Message reReceivedMessage = consumer.receive(1000);
+ Assertions.assertNull(reReceivedMessage);
+
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ @Tag("IntegrationTest")
+ void unorderedAckSyncTest() {
+ try {
+ Session session = JmsSqsSyncStandard.createUnorderedAcknowledgeSession(connection);
+ Queue queue = session.createQueue(QUEUE_NAME);
+ MessageProducer producer = session.createProducer(queue);
+ TextMessage message = session.createTextMessage("Hello World!");
+ producer.send(message);
+ JmsSqsSyncStandard.receiveMessageExplicitAckSync(connection, session, queue);
+
+ MessageConsumer consumer = session.createConsumer(queue);
+ connection.start();
+ Message reReceivedMessage = consumer.receive(1000);
+ Assertions.assertNull(reReceivedMessage);
+
+ } catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ @Tag("IntegrationTest")
+ void fifoQueueWorks() {
+ Assertions.assertDoesNotThrow(() -> JmsSqsSyncFifo.main(null));
+ }
+}
\ No newline at end of file
diff --git a/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/AsyncMessageReceiverTest.java b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/AsyncMessageReceiverTest.java
new file mode 100644
index 00000000000..0def734d3a4
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/AsyncMessageReceiverTest.java
@@ -0,0 +1,47 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.JMSException;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse;
+
+class AsyncMessageReceiverTest {
+private static final Logger LOGGER = LoggerFactory.getLogger(AsyncMessageReceiverTest.class);
+ @AfterEach
+ void tearDown() throws JMSException {
+ SqsJmsExampleUtils.cleanUpExample(AsyncMessageReceiver.QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT );
+ }
+
+ @Test
+ @Tag("IntegrationTest")
+ void doReceiveMessageAsyncTest() {
+ try {
+ new Thread(SqsJmsExampleUtils.sendAMessageAsync(AsyncMessageReceiver.QUEUE_NAME, 3L, 5, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT)).start();
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ try {
+ AsyncMessageReceiver.doReceiveMessageAsync();
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+
+ // Use plain SQS test to make sure there are no messages in the queue.
+ try (SqsClient sqsClient = SqsClient.create()) {
+ ReceiveMessageResponse response = sqsClient.receiveMessage(b -> b.queueUrl(sqsClient
+ .getQueueUrl(builder -> builder
+ .queueName(AsyncMessageReceiver.QUEUE_NAME)).queueUrl()));
+
+ Assertions.assertFalse(response.hasMessages());
+ }
+ }
+}
\ No newline at end of file
diff --git a/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverClientAckTest.java b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverClientAckTest.java
new file mode 100644
index 00000000000..0f343663f9e
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverClientAckTest.java
@@ -0,0 +1,43 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.JMSException;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse;
+
+class SyncMessageReceiverClientAckTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SyncMessageReceiverClientAckTest.class);
+
+ @AfterEach
+ void tearDown() throws JMSException {
+ SqsJmsExampleUtils.cleanUpExample(SyncMessageReceiverClientAcknowledge.QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT );
+ }
+
+ @Test
+ @Tag("IntegrationTest")
+ void doReceiveMessagesSyncClientAcknowledgeTest() {
+ try {
+ SyncMessageReceiverClientAcknowledge.doReceiveMessagesSyncClientAcknowledge();
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+
+ // Use plain SQS test to make sure there are no messages in the queue.
+ try (SqsClient sqsClient = SqsClient.create()) {
+ ReceiveMessageResponse response = sqsClient.receiveMessage(b -> b.queueUrl(sqsClient
+ .getQueueUrl(builder -> builder
+ .queueName(SyncMessageReceiverClientAcknowledge.QUEUE_NAME)).queueUrl()));
+
+ Assertions.assertFalse(response.hasMessages());
+ }
+ }
+}
\ No newline at end of file
diff --git a/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverTest.java b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverTest.java
new file mode 100644
index 00000000000..5d0aa7825cc
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverTest.java
@@ -0,0 +1,47 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.JMSException;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse;
+
+class SyncMessageReceiverTest {
+private static final Logger LOGGER = LoggerFactory.getLogger(SyncMessageReceiverTest.class);
+ @AfterEach
+ void tearDown() throws JMSException {
+ SqsJmsExampleUtils.cleanUpExample(SyncMessageReceiver.QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT );
+ }
+
+ @Test
+ @Tag("IntegrationTest")
+ void doReceiveMessageSyncTest() {
+ try {
+ new Thread(SqsJmsExampleUtils.sendAMessageAsync(SyncMessageReceiver.QUEUE_NAME, 10L, 1, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT)).start();
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ try {
+ SyncMessageReceiver.doReceiveMessageSync();
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+
+ // Use plain SQS test to make sure there are no messages in the queue.
+ try (SqsClient sqsClient = SqsClient.create()) {
+ ReceiveMessageResponse response = sqsClient.receiveMessage(b -> b.queueUrl(sqsClient
+ .getQueueUrl(builder -> builder
+ .queueName(SyncMessageReceiver.QUEUE_NAME)).queueUrl()));
+
+ Assertions.assertFalse(response.hasMessages());
+ }
+ }
+}
\ No newline at end of file
diff --git a/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverUnorderedAckTest.java b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverUnorderedAckTest.java
new file mode 100644
index 00000000000..7e4e217669c
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/SyncMessageReceiverUnorderedAckTest.java
@@ -0,0 +1,44 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import com.example.sqs.jms.SqsJmsExampleUtils;
+import jakarta.jms.JMSException;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.sqs.SqsClient;
+import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse;
+
+class SyncMessageReceiverUnorderedAckTest {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SyncMessageReceiverUnorderedAckTest.class);
+
+ @AfterEach
+ void tearDown() throws JMSException {
+ SqsJmsExampleUtils.cleanUpExample(SyncMessageReceiverUnorderedAcknowledge.QUEUE_NAME, SqsJmsExampleUtils.QUEUE_VISIBILITY_TIMEOUT );
+ }
+
+ @Test
+ @Tag("IntegrationTest")
+ void doReceiveMessagesSyncUnorderedAcknowledgeTest() {
+ try {
+ SyncMessageReceiverUnorderedAcknowledge.doReceiveMessagesUnorderedAcknowledge();
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+
+ // Use plain SQS test to make sure there are no messages in the queue.
+ try (SqsClient sqsClient = SqsClient.create()) {
+ ReceiveMessageResponse response = sqsClient.receiveMessage(b -> b.queueUrl(sqsClient
+ .getQueueUrl(builder -> builder
+ .queueName(SyncMessageReceiverUnorderedAcknowledge.QUEUE_NAME)).queueUrl()));
+
+ Assertions.assertFalse(response.hasMessages());
+ }
+ }
+}
\ No newline at end of file
diff --git a/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/TextMessageSenderTest.java b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/TextMessageSenderTest.java
new file mode 100644
index 00000000000..e6b47326c05
--- /dev/null
+++ b/javav2/example_code/sqs-jms/src/test/java/com/example/sqs/jms/stdqueue/TextMessageSenderTest.java
@@ -0,0 +1,17 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package com.example.sqs.jms.stdqueue;
+
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class TextMessageSenderTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TextMessageSenderTest.class);
+ @Test
+ void doSendTextMessageTest() {
+ // The TextMessageSender.doSendTextMessage() can't be tested with an automated test because it requires user input.
+ }
+
+}
\ No newline at end of file
diff --git a/javav2/example_code/sqs/README.md b/javav2/example_code/sqs/README.md
index 99a931137c8..194236086be 100644
--- a/javav2/example_code/sqs/README.md
+++ b/javav2/example_code/sqs/README.md
@@ -56,6 +56,7 @@ functions within the same service.
- [Create and publish to a FIFO topic](../sns/src/main/java/com/example/sns/PriceUpdateExample.java)
- [Process S3 event notifications](../s3/src/main/java/com/example/s3/ProcessS3EventNotification.java)
- [Publish messages to queues](../../usecases/topics_and_queues/src/main/java/com/example/sns/SNSWorkflow.java)
+- [Use the Amazon SQS Java Messaging Library to work with the JMS interface](../sqs-jms/src/main/java/com/example/sqs/jms/stdqueue/TextMessageSender.java)
- [Work with queue tags](src/main/java/com/example/sqs/TagExamples.java)
@@ -116,9 +117,21 @@ This example shows you how to do the following:
+#### Use the Amazon SQS Java Messaging Library to work with the JMS interface
+
+This example shows you how to use the Amazon SQS Java Messaging Library to work with the JMS interface.
+
+
+
+
+
+
+
+
+
#### Work with queue tags
-This example shows you how to perform tagging operation with Amazon SQS
+This example shows you how to perform tagging operation with Amazon SQS.
diff --git a/php/applications/photo_asset_manager/bootstrap.zip b/php/applications/photo_asset_manager/bootstrap.zip
deleted file mode 100644
index 69cebcb07a4..00000000000
Binary files a/php/applications/photo_asset_manager/bootstrap.zip and /dev/null differ