DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Keep Your Application Secrets Secret
  • Efficiently Reading Large Excel Files (Over 1 Million Rows) Using the Open-Source Sjxlsx Java API
  • How to Migrate from Java 8 to Java 17+ Using Amazon Q Developer
  • Video Generation With Java: Leverage Nova and Amazon Bedrock

Trending

  • Bringing Intelligence Closer to the Source: Why Real-Time Processing is the Heart of Edge AI
  • AI Agents in Java: Architecting Intelligent Health Data Systems
  • Feature Flag Debt: Performance Impact in Enterprise Applications
  • RAG Is Not Enough: Advanced Retrieval Architectures Using Vertex AI Search on GCP
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Using SQS With JMS for Legacy Applications

Using SQS With JMS for Legacy Applications

In this article, take an in-depth look at the steps to integrate a legacy Java application with SQS through JMS.

By 
Balaji Nagarajan user avatar
Balaji Nagarajan
·
Aug. 21, 24 · Tutorial
Likes (9)
Comment
Save
Tweet
Share
10.7K Views

Join the DZone community and get the full member experience.

Join For Free

As part of migrating Java enterprise applications to the cloud, it is beneficial to replace parts of the technology stack with equivalent cloud services. As an example, traditional messaging services are being replaced by Amazon SQS as part of the migration to AWS. Java Messaging Service (JMS) has been a mainstay in the technology stack of Java enterprise applications. The support provided by SQS for the JMS standard helps with an almost seamless technology replacement. In this article, I have described the steps to integrate a legacy Java application with SQS through JMS.

Legacy Java Application

For the purposes of this article, a legacy Java application has the following characteristics:

  1. Uses the JMS standard to interact with messaging services
  2. The application is not built using Maven/Gradle or any other package dependency managers as part of Java code build and packaging.

Maven "Uber JAR" Approach

The AWS Java SDK, which contains the Java Messaging Service library for SQS, requires the use of Maven or Gradle to set up the development environment and write code that uses various AWS services. As the legacy application does not use Maven/Gradle, we will use an approach called the "Uber JAR" approach.

In this approach, a Maven project outside the source tree of the legacy application will be created. This Maven project will use the packaging capability of Maven to create an Uber JAR, which is basically a JAR file containing the Java messaging library for SQS and all its direct and transitive dependencies. For example, the SQS Java messaging library depends on the base SQS library which, in turn, has a dependency on multiple Apache libraries (among many other dependencies). All these libraries are packaged into one JAR file. This JAR file can then be added to the classpath of the legacy application and included in its deployment packages. 

An example pom file to create the Uber JAR is given below.

XML
 
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example.aws</groupId>
	<artifactId>sqssample</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>jar</packaging>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.shade.plugin.version>3.2.1</maven.shade.plugin.version>
		<maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version>
		<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>com.amazonaws</groupId>
			<artifactId>amazon-sqs-java-messaging-lib</artifactId>
			<version>2.0.0</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>${maven.compiler.plugin.version}</version>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>${maven.shade.plugin.version}</version>
				<configuration>
					<createDependencyReducedPom>false</createDependencyReducedPom>
					<finalName>sqsjmssample</finalName>
				</configuration>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>


Running "mvn package" for this pom will create the Uber JAR file, sqsjmssample.jar. This JAR file should then be added to the classpath of the legacy application just like any other third-party library.

Maven Shading

What happens if the SQS library and the legacy Java application depend on the same open-source library but different versions? This can cause subtle issues during the runtime that affect the functioning of both the application and SQS library.  In the pom file above, you will notice that the Maven shade plugin is being used. As part of creating the Uber JAR, this plugin can rename packages of the dependencies. Assuming that both the SQS library and the Java application depend on different versions of Apache libraries, adding the shading configuration given below will avoid any issues during runtime.

XML
 
					<relocations>
						<relocation>
							<pattern>org.apache</pattern>
							<shadedPattern>software.amazon.awssdk.thirdparty.org.apache</shadedPattern>
						</relocation>
					</relocations>


This snippet has to be added under the <configuration> section of the shade plugin declaration in the pom file. You will notice that Uber JAR built with this configuration has all the Apache libraries moved to the software.amazon.awssdk.thirdparty.org.apache.** packages. The shade plugin also repoints any dependencies on the Apache libraries to these new code packages.

Sample Java Code

Now that we have the Uber JAR, let us look at a sample Java code to send a message to a queue destination.

Java
 
		SqsClient sqsClient = SqsClient.builder().region(Region.US_EAST_1).build();
		try {
			String queueName = "myqueue";
			String message = "Test Message";
			// Create the connection factory based on the config
			SQSConnectionFactory connectionFactory = new SQSConnectionFactory(new ProviderConfiguration(),
					SqsClient.builder().region(Region.US_EAST_1).build());

			// Create the connection
			SQSConnection connection = connectionFactory.createConnection();

			// Create the session
			Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
			MessageProducer producer = session.createProducer(session.createQueue(queueName));
			TextMessage txtmessage = session.createTextMessage(message);
			producer.send(txtmessage);
			connection.close();
		} catch (SqsException e) {
			System.err.println(e.awsErrorDetails().errorMessage());
			System.exit(1);
		} catch (JMSException e) {
			e.printStackTrace();
		}


Note that apart from the SQSConnectionFactory and SQSConnection, the rest of the code uses standard JMS types.

Ideally, the existing messaging service can be replaced by SQS without any code changes to the Java application. Just changing the Application Server configuration for the JMS resources involved (to point to SQS Queues and Connection Factories) should suffice. This approach would require a JCA (Java Connector Architecture)-compliant Resource Adapter implementation for SQS. Even though there are some open-source SQS Resource Adapter implementations, the SQS Java Messaging library does not include one. Of course, using the open-source Resource Adapters carries licensing and support risks.

Design Considerations

  • As we saw above with the Maven shading approach, the code packages of open-source libraries can be changed. This could trip up the vulnerability reports produced by OSS (Open Source Software) scanners. So, it is important to set up the Maven project also as another code stream that would go through the same security scans as the Java application codebase.
  • The Uber JAR approach discussed above can be used for any AWS service. For example, the Java Application could be modernized to store documents in S3 buckets instead of in the application database. So, it is important to consider the range of AWS services to be used by the application while setting up the required Maven dependencies, to avoid creating numerous Uber JARs with duplicate code.
  • The SQS Java Messaging Library does not support Distributed (XA) transactions. If the Java application being migrated requires the messaging provider to support distributed transactions, Amazon MQ (Active MQ) could be a better choice than SQS. Alternatively, the application may have to be refactored to use a pseudo-distributed transaction pattern like SAGA OR to avoid using distributed transactions altogether.
AWS Open source JAR (file format) Java (programming language) Enterprise application integration

Opinions expressed by DZone contributors are their own.

Related

  • Keep Your Application Secrets Secret
  • Efficiently Reading Large Excel Files (Over 1 Million Rows) Using the Open-Source Sjxlsx Java API
  • How to Migrate from Java 8 to Java 17+ Using Amazon Q Developer
  • Video Generation With Java: Leverage Nova and Amazon Bedrock

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook