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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Keep Your Application Secrets Secret
  • Video Generation With Java: Leverage Nova and Amazon Bedrock
  • Leverage Amazon BedRock Chat Model With Java and Spring AI
  • How to Quarantine a Malicious File in Java

Trending

  • How Kubernetes Cluster Sizing Affects Performance and Cost Efficiency in Cloud Deployments
  • AI Speaks for the World... But Whose Humanity Does It Learn From?
  • Orchestrating Microservices with Dapr: A Unified Approach
  • How to Ensure Cross-Time Zone Data Integrity and Consistency in Global Data Pipelines
  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
9.9K 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
  • Video Generation With Java: Leverage Nova and Amazon Bedrock
  • Leverage Amazon BedRock Chat Model With Java and Spring AI
  • How to Quarantine a Malicious File in Java

Partner Resources

×

Comments
Oops! Something Went Wrong

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

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

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 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!