Amazon Q: Legacy Java Migration to AWS Graviton Containers
Learn how Amazon Q Developer helps modernize Java 8 apps to containerized Java 21 applications optimized for AWS Graviton on Amazon EKS.
Many organizations still operate business-critical applications on Java 8, which has reached its end of public updates. These applications often miss out on the performance improvements, security enhancements, and cost optimizations available in newer technologies.
Amazon Q Developer serves as an intelligent assistant throughout this modernization journey. Using the Amazon Q Developer CLI, you can get step-by-step guidance, troubleshooting help, and best practices for each phase of the migration. Our modernization journey involves four key steps:
- Upgrading from Java 8 to Java 21 using Amazon Q Transformation CLI
- Identifying and resolving source code and library dependencies for Graviton migration using Porting Advisor for Graviton . Fix identified issues with Amazon Q Developer CLI
- Containerizing the application using Amazon Q Developer CLI
- Deploying on Amazon EKS using cost-effective Graviton processors using Amazon Q Developer CLI
Prerequisites
- Amazon Q Developer access
- Git installed
- Python virtual environment capability
- Porting Advisor for Graviton installed
- Amazon Q Developer CLI and Amazon Q Developer Transformation CLI installed
- Basic understanding of Java build systems
Implementation steps
Step 1 : Initiate Q CLI chat and clone the repository from github
First, I prompted Amazon Q CLI chat to clone the sample repository.
Step 2 : Planning the Modernization with Q Developer CLI
Then I ask Amazon Q CLI to lay out the steps needed to modernize this application.
> This is a legacy application in Java 8. I need to upgrade the Java 8 to Java 21 and then to containerize on Amazon EKS and run on Graviton powered instances. Analyze this code base for Native code and dependencies. Use Amazon Q Code transformation and AWS graviton porting advisor as well in the steps. Ensure all dependencies are compatible with ARM64 architecture. Minimize the use of exceptions, especially in hot code paths, as they can be more costly on Graviton platforms. Employ Java's Optional class to handle potential null values, reducing the need for NullPointerException. Create a high level plan to achieve this goal. Ask me any clarifying questions before proceeding. Amazon Q asked me follow up questions and I answered them
plaintext
1. Does your application have any external system dependencies (databases, message queues, etc.) that need to be considered in the migration? H2 database2. Are there any specific performance requirements or SLAs that need to be maintained during and after migration? Highly Scalable3. Do you have existing CI/CD pipelines that need to be updated, or should we create new ones? Create a new one4. Are there any specific security requirements or compliance considerations for the containerized application? Standard security requirements5. What is your timeline for this migration? Would you prefer a phased approach or a complete cutover? Phased6. Do you have existing test coverage that can validate the migration, or do we need to develop additional tests? Develop additional tests7. Are there any specific parts of the application that you're concerned about regarding the Java 21 upgrade or Graviton compatibility? Please recommend based on code base
Based on the responses, Q refined the migration plan addressing and identifying any specific concerns for Java 21 and Graviton compatibility.
plaintext
# Upgrading and Containerizing Your Unicorn Manager ApplicationHere's a high-level plan to upgrade your Java 8 application to Java 21, containerize it, and deploy on Amazon EKS with Graviton-based instances:## Phase 1: Java 8 to Java 21 Migration1. Assess compatibility• Run Amazon Q Code Transformation to analyze your codebase• Identify deprecated APIs and language features2. Update dependencies• Update Spring Boot from 2.7.18 to 3.x (which supports Java 21)• Update other dependencies in your pom.xml to versions compatible with Java 21• Replace any deprecated libraries with modern alternatives3. Code modifications• Apply Amazon Q Code Transformation recommendations• Update code to use Java 21 features where beneficial• Update JUnit tests to work with newer versions4. Build and test• Configure Maven to use Java 21• Run comprehensive tests to ensure functionality is preserved• Fix any runtime issues that weren't caught by static analysis## Phase 2: Graviton Preparation1. Run AWS Graviton Porting Advisor• Analyze your application for ARM64 compatibility• Identify any x86-specific code or dependencies• Review recommendations for optimization2. Address architecture-specific issues• Update any native libraries to support ARM64• Fix any architecture-dependent code• Test on ARM64 development environment if possible## Phase 3: Containerization1. Create Dockerfile• Use multi-stage builds for efficiency• Start with a Java 21 base image• Configure proper JVM settings for containers• Include only necessary artifacts2. Optimize for containers• Configure memory limits appropriate for containerized JVM• Implement health checks• Set up proper logging to stdout/stderr• Externalize configuration3. Multi-architecture container build• Update Dockerfile to support multi-architecture builds• Use Docker buildx or similar tools to create multi-arch images• Push to Amazon ECR with support for both x86_64 and ARM64## Phase 4: EKS Deployment1. Set up Amazon EKS cluster• Create a cluster with mixed instance types (both x86 and Graviton)• Configure node groups with appropriate instance types• Set up proper IAM roles and networking2. Create Kubernetes manifests• Define deployments, services, and other resources• Configure resource requests and limits• Set up node affinity for Graviton instances• Implement proper liveness and readiness probes3. CI/CD pipeline• Set up automated build and deployment• Configure testing in the pipeline• Implement blue/green or canary deployment strategies4. Monitoring and optimization• Set up CloudWatch or Prometheus/Grafana for monitoring• Configure proper logging with CloudWatch Logs• Analyze performance and cost metrics• Optimize resource allocation based on actual usage## Tools to Use1. Amazon Q Code Transformation• Use for automated code analysis and transformation• Get recommendations for Java 8 to 21 migration• Identify potential issues and their solutions2. AWS Graviton Porting Advisor• Analyze compatibility with ARM64 architecture• Identify architecture-specific code• Get recommendations for optimizing for Graviton3. Amazon ECR• Store your container images• Support for multi-architecture images• Integration with EKS4. AWS App2Container• Optional tool to help containerize existing applications• Generates artifacts needed for containerization5. Amazon EKS• Managed Kubernetes service for container orchestration• Support for both x86 and Graviton instances• Scalability and high availability## Key Recommendations for Java 21 and Graviton CompatibilityBased on your codebase, Venu, here are specific recommendations:1. Replace EntityNotFoundException with Optional pattern:• Your service layer throws exceptions for not found entities• This is inefficient on Graviton and can be replaced with Optional2. Update validation annotations:• Migrate from javax.validation to jakarta.validation• This is required for Spring Boot 3.x compatibility3. Implement Virtual Threads:• Your application has several I/O operations that would benefit from virtual threads• This will improve scalability on Graviton instances4. Configure ZGC for ARM64:• ZGC performs well on ARM64 architecture• Configure with generational collection for better performance5. Implement health checks:• Add Spring Boot Actuator for comprehensive health monitoring• This is crucial for container orchestration in EKS6. Optimize container resource settings:• Graviton instances have different performance characteristics• Start with conservative resource limits and adjust based on monitoringThis approach allows for a phased migration, reducing risk and allowing for testing at each stage. You can also run both versions in parallel during the transition to ensure a smoothcutover.
Amazon Q provided detailed steps on how to perform the modernization with right tools and services. I also ask Q to save this plan for future steps.
> Save this plan to plan.md Step 3 : Use Q Transformation CLI to transform this project to Java 21
> python -m venv qct-cli
> source qct-cli/bin/activate
> which qct > qct configure and follow the prompts
> qct transform --source_folder /home/******/qctcli/UnicornDemo --target_version 21
Amazon Q Transformation agent will start the upgrade process and create a new local branch with the changes.plaintext
[ec2-user@ip-172-31-37-67 UnicornDemo]$ qct transform --source_folder /home/ec2-user/qctcli/UnicornDemo --target_version 21Running command: mvn --version at: /home/ec2-user/qctcli/UnicornDemoFinish running command: mvn --version, return code: 0Your Maven version is supported for transformations.params = {'source_folder': '/home/ec2-user/qctcli/UnicornDemo', 'target_version': <JavaVersion.JAVA_21: '21'>, 'build_tool': 'maven'}Running command: git checkout -B mainline at: /home/ec2-user/qctcli/UnicornDemoFinish running command: git checkout -B mainline, return code: 0........Running command: git commit -m 58cfef81-2826-44f2-8f29-dbf18e557be4 at: /home/ec2-user/qctcli/UnicornDemoFinish running command: git commit -m 58cfef81-2826-44f2-8f29-dbf18e557be4, return code: 0Final transformation status: COMPLETEDEnding Transformation for: 58cfef81-2826-44f2-8f29-dbf18e557be4
Step 3 : Use Amazon Q CLI to install and invoke Graviton Porting advisor to check for any compatibility issues in porting
> Can you run Porting advisor for Graviton on UnicornDemo project If Porting Advisor is not installed, Q CLI will install that as well before running.
plaintext
I'll help you run AWS Porting Advisor for Graviton on your UnicornDemo project. First, let's check if the Porting Advisor tool is installed and then run it on your project.Let me check if the UnicornDemo project exists in your current directory:Read from filesystem▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Reading directory: /home/ec2-user/qctcli with maximum depth of 0Reading from filesystem...▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Reading:🟢 Completed in 0.1sGreat! I can see that you have both the UnicornDemo project and the porting-advisor-for-graviton tool in your directory. Let's run the Porting Advisor for Graviton on your UnicornDemoproject:Execute shell command▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔I will run the following shell command:cd /home/ec2-user/qctcli/porting-advisor-for-graviton && python3 -m porting_advisor.main /home/ec2-user/qctcli/UnicornDemo --output-format html......Great! I've successfully run the AWS Porting Advisor for Graviton on your UnicornDemo project. The analysis has been completed and the report has been saved to/home/ec2-user/qctcli/UnicornDemo-graviton-report.html.Here's a summary of the findings:1. The tool scanned 13 files in your UnicornDemo project.2. Positive findings:• Detected Java code. The tool recommends using Amazon Corretto, which is AWS's distribution of OpenJDK that's optimized for Graviton processors. You can find more details at https://aws.amazon.com/corretto/3. Neutral findings:• Java version requirements: Minimum version 8 is required, but version 11 or above is recommended for optimal performance on Graviton. More details are available at https://github.com/aws/aws-graviton-getting-started/blob/main/java.mdThe good news is that no critical issues were found that would prevent your UnicornDemo project from running on AWS Graviton processors. The recommendations are primarily around usingAmazon Corretto.Would you like me to help you with implementing any of these recommendations for your UnicornDemo project?
If there are critical findings, you can ask Amazon Q CLI to fix it as well for you. Since there are no critical findings in this project, I will skip this step.
Step 4 : Use Amazon Q CLI to Containerize the application
> Containerize the application so that it can be deployed in Amazon EKS with Graviton instances Amazon Q will create necessary files to make this project a container based application including Docker file and Kubernetes configuration files.
plaintext
I'll help you containerize the UnicornDemo application for deployment on Amazon EKS with Graviton instances. Let's create the necessary Docker configuration files and make any requiredadjustments to ensure compatibility with ARM64 architecture used by Graviton.Write to filesystem▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Path: /home/ec2-user/qctcli/UnicornDemo/Dockerfile+ 1: FROM amazoncorretto:21-al2023-jdk+ 2:+ 3: WORKDIR /app+ 4:+ 5: # Copy the Maven POM and source code+ 6: COPY pom.xml .+ 7: COPY src ./src+ 8:+ 9: # Build the application+ 10: RUN yum install -y maven && \+ 11: mvn package -DskipTests && \+ 12: yum clean all && \+ 13: rm -rf /var/cache/yum+ 14:+ 15: # Use a smaller runtime image+ 16: FROM amazoncorretto:21-al2023+ 17:+ 18: WORKDIR /app+ 19:+ 20: # Copy the built artifact from the build stage+ 21: COPY --from=0 /app/target/unicorn-manager-*.jar app.jar+ 22:+ 23: # Expose the application port+ 24: EXPOSE 8080+ 25:+ 26: # Set the command to run the application+ 27: ENTRYPOINT ["java", "-jar", "app.jar"]
Amazon Q has containerized the application and provides the summary of changes.
plaintext
I've containerized your UnicornDemo application for deployment on Amazon EKS with Graviton instances. Here's what I've created:## 1. Containerization• **Dockerfile**: Created a multi-stage build using Amazon Corretto 21 (Amazon's optimized JDK for AWS, including Graviton support)• First stage builds the application with Maven• Second stage creates a minimal runtime image• **Added Spring Boot Actuator**: For health checks and monitoring in Kubernetes## 2. Kubernetes ConfigurationCreated a complete set of Kubernetes manifests in the kubernetes/ directory:• **deployment.yaml**: Configures the deployment with:• Resource limits and requests• Health probes• Node selector for Graviton instances (kubernetes.io/arch: arm64)• Environment variables for Spring profiles• **service.yaml**: Exposes the application within the cluster• **ingress.yaml**: Configures AWS Application Load Balancer for external access## 3. Production Configuration• **application-prod.properties**: Added production-specific configuration with:• Database settings• Actuator endpoints for health checks• Performance tuning for Tomcat## 4. Deployment Scripts• **build-and-push.sh**: Script to:• Build the Docker image for ARM64 architecture• Create an ECR repository if needed• Push the image to Amazon ECR• Update Kubernetes manifests with your AWS account details• **eks-cluster-setup.sh**: Script to:• Create an EKS cluster• Add a Graviton node group (m6g.large instances)• Set up the AWS Load Balancer Controller for ingress## 5. Documentation• Updated the README.md with:• New project structure• Deployment instructions• Graviton compatibility details• Updated tech stack information## How to Deploy1. Build and push the Docker image:bash./build-and-push.sh2. Create an EKS cluster with Graviton nodes (if you don't have one):bash./eks-cluster-setup.sh3. Deploy to EKS:bashkubectl apply -f kubernetes/4. Verify the deployment:bashkubectl get pods -l app=unicorn-managerkubectl get svc unicorn-managerkubectl get ingress unicorn-manager-ingressThe application is now optimized for AWS Graviton with:• Amazon Corretto 21 JDK (optimized for ARM64)• ARM64-specific Docker image• Node selector targeting Graviton instances• Spring Boot 3.x and Java 21 for improved performance on ARM64
Step 5 : Use Amazon Q CLI to deploy the application to AWS
> Please deploy this application to my AWS environment plaintext
I'll help you deploy the UnicornDemo application to your AWS environment. To do this properly, I'll need to execute several steps to build the container image, push it to ECR, and deploy itto EKS.Before proceeding, I should note that this will involve:1. Building a Docker image2. Creating an ECR repository3. Pushing the image to ECR4. Creating or using an existing EKS cluster5. Deploying the application to the cluster
Amazon Q has successfully deployed the application to EKS using Graviton instances. It encountered a few errors while deploying but corrected them and re-deployed successfully.
Benefits of This Modernization Approach
By leveraging Amazon Q to orchestrate this modernization journey, organizations can achieve:
- Reduced Migration Time: Automated code transformation and guided steps significantly accelerate the modernization process
- Lower Risk: Systematic approach with testing at each phase minimizes disruption
- Cost Optimization: Graviton instances offer up to 40% better price/performance compared to x86
- Performance Improvements: Java 21 and containerization bring significant performance enhancements
- Future-Readiness: Modern infrastructure enables easier adoption of new technologies
Conclusion
Modernizing legacy Java applications doesn't have to be a daunting task. With Amazon Q orchestrating the journey, organizations can systematically transform their Java 8 applications into modern, containerized Java 21 applications running efficiently on AWS Graviton-powered Amazon EKS.
The agentic capabilities of Amazon Q CLI make it possible to get contextual guidance at each step, automate complex transformations, and follow best practices throughout the modernization process. This not only accelerates the journey but also ensures that the resulting application is optimized for performance, cost, and maintainability in the cloud-native era.
By embracing this approach, organizations can breathe new life into their legacy applications and position themselves for continued innovation in the rapidly evolving technology landscape.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article