This repository demonstrates end-to-end Java application modernization using GitHub Copilot App Modernization extension. It showcases a complete journey from a legacy Java 8 / Spring Boot 2.7 application with AWS dependencies to a modern, containerized, cloud-native application running on Azure.
- Overview
- About Assets Manager
- Architecture Evolution
- Prerequisites
- Getting Started
- Solution Structure
- Branch Structure
- Modernization Guide
- Contributing
This repository serves as a hands-on sample for modernizing legacy Java applications using AI-powered tools. The main branch contains the original legacy codebase, and each subsequent branch represents a stage in the modernization process, driven by GitHub Copilot.
Assess β Upgrade β Unit Tests β CVE Check β Cloud Migration Readiness β Containerize β Deploy
Each branch demonstrates:
- β Specific modernization tasks completed
- π Code changes and refactoring
- π§ Configuration updates
- π Documentation and lessons learned
Assets Manager is a file management application that showcases common patterns found in enterprise Java applications. It's an ideal candidate for modernization as it contains:
- Multi-module Maven project structure
- AWS SDK dependencies (S3 storage)
- Older Java and Spring Boot versions
- Message-driven processing with RabbitMQ
- Relational data access with Spring Data JPA
| Component | Technology |
|---|---|
| Language | Java 8 |
| Framework | Spring Boot 2.7.18 |
| Build Tool | Maven 3.x |
| ORM | Spring Data JPA / Hibernate |
| Messaging | RabbitMQ via Spring AMQP |
| File Storage | AWS S3 |
| Database | PostgreSQL |
| Hosting | Local / bare-metal |
| Component | Technology |
|---|---|
| Language | Java 21 |
| Framework | Spring Boot 3.3.7 |
| Build Tool | Maven 3.x |
| ORM | Spring Data JPA / Hibernate (Jakarta EE) |
| Messaging | RabbitMQ via Spring AMQP |
| File Storage | Azure Blob Storage |
| Database | PostgreSQL |
| Hosting | Azure Container Apps |
| Containerization | Docker (multi-stage builds) |
User β Web App (HTTP/8080) β AWS S3 (file upload)
β RabbitMQ (publish message)
β PostgreSQL (metadata)
RabbitMQ β Worker App β AWS S3 (download/upload thumbnail)
β PostgreSQL (update metadata)
User β Web App (HTTP/8080) β Azure Blob Storage (file upload, Managed Identity)
β RabbitMQ (publish message)
β PostgreSQL (metadata)
RabbitMQ β Worker App β Azure Blob Storage (download/upload thumbnail)
β PostgreSQL (update metadata)
- π€ File Upload: Upload images through a web UI
- πΌοΈ Thumbnail Generation: Automatic background processing via message queue
- π Image Metadata: Track uploaded files and their processing status
- π File Browsing: View and manage uploaded assets
- JDK 8 (or use the provided dev container β see DEV-SETUP.md)
- Maven 3.x
- PostgreSQL 16
- RabbitMQ 3.x
- AWS credentials (for S3 storage) or use
devprofile for local file storage
- IDE:
- Visual Studio Code with Java Extension Pack and GitHub Copilot
- OR IntelliJ IDEA with GitHub Copilot plugin
- JDK 21 (or use the dev container)
- Docker Desktop (for containerization stages)
- Azure Account (for cloud deployment)
- Azure CLI and Azure Developer CLI (azd) (for Azure deployment)
- Git
The easiest way to get started is with the included dev container, which provides all dependencies automatically. See DEV-SETUP.md for setup instructions.
-
Clone the repository
git clone https://github.com/sitoader/ghcp-java-app-moderization-sample.git cd ghcp-java-app-moderization-sample -
Open in a dev container (recommended)
- VS Code: Command Palette β Dev Containers: Reopen in Container β select Asset Manager - JDK 8 (Source)
- Or install JDK 8, PostgreSQL, and RabbitMQ locally
-
Run the application
# Start the web module ./mvnw -pl web spring-boot:run # In a separate terminal, start the worker module ./mvnw -pl worker spring-boot:run
-
Open the app
Service URL Credentials Web app http://localhost:8080 β RabbitMQ management http://localhost:15672 guest/guest
# List all branches
git branch -a
# Switch to a specific branch (e.g., java-upgrade)
git checkout java-upgrade
# Compare changes between stages
git diff main..assess
git diff main..java-upgrade
git diff java-upgrade..resolve-CVEsghcp-java-app-moderization-sample/
|ββ web/ # Web application module
β βββ pom.xml
β βββ Dockerfile
β βββ src/main/java/com/microsoft/migration/assets/
β βββ AssetsManagerApplication.java # Entry point
β βββ config/ # Configuration classes
β βββ controller/ # MVC controllers
β βββ model/ # Domain models
β βββ service/ # Business logic
β
βββ worker/ # Worker application module
β βββ pom.xml
β βββ Dockerfile
β βββ src/main/java/com/microsoft/migration/assets/worker/
β βββ WorkerApplication.java # Entry point
β βββ config/ # Configuration classes
β βββ model/ # Domain models
β βββ service/ # Processing services
β
βββ infra/ # Azure infrastructure (Bicep)
β βββ main.bicep
β βββ main.bicepparam
β βββ postgres/Dockerfile
β βββ rabbitmq/Dockerfile
β
βββ doc-media/ # Documentation images
This repository uses a branch-per-stage approach to demonstrate the modernization journey:
| Branch | Stage | Description |
|---|---|---|
main |
Legacy Application | Original Java 8 / Spring Boot 2.7.18 codebase with AWS S3 β starting point |
assess |
Assessment & Planning | Assessment report capturing current state analysis, modernization targets, risks, and recommended action plan |
java-upgrade |
Framework Upgrade | Incremental upgrade: Java 8 β 17 β 21, Spring Boot 2.7 β 3.2 β 3.3 with Jakarta EE migration |
java-upgrade-unit-tests |
Unit Testing | Comprehensive unit tests for web and worker modules to validate post-upgrade behavior |
resolve-CVEs |
Security Scan | Vulnerability assessment, CVE remediation, and dependency updates |
migration-AWS-to-Azure |
Cloud Migration | Migrate from AWS S3 to Azure Blob Storage with Managed Identity authentication |
containerized_app |
Containerization | Multi-stage Dockerfiles, Docker Compose, and Azure deployment infrastructure (Bicep) |
main (Java 8, Spring Boot 2.7, AWS S3)
βββ assess (assessment report & modernization plan)
βββ java-upgrade (Java 21, Spring Boot 3.3.7)
βββ java-upgrade-unit-tests (+ comprehensive tests)
βββ resolve-CVEs (+ vulnerability fixes)
βββ migration-AWS-to-Azure (AWS S3 β Azure Blob Storage)
βββ containerized_app (+ Docker, Compose, Azure infra)
- Start with
main: Understand the legacy application - Review
assess: See the assessment report and modernization plan - Review
java-upgrade: See the incremental Java/Spring Boot upgrade path - Explore improvements:
java-upgrade-unit-testsandresolve-CVEsbranch - Follow the cloud migration:
migration-AWS-to-Azurereplaces AWS with Azure services - Review containerization:
containerized_appadds Docker, Compose, and Azure deployment infrastructure - Compare changes: Use
git diffto see what changed between stagesgit diff main..assess git diff main..java-upgrade git diff java-upgrade..migration-AWS-to-Azure git diff migration-AWS-to-Azure..containerized_app
This guide walks through each stage of modernizing the Assets Manager application using GitHub Copilot App Modernization. Each stage builds on the previous one.
π‘ Tip: Work through these stages sequentially. Each stage has dependencies on the previous stages' outputs.
Objective: Analyze the current application architecture, identify modernization opportunities, and create a comprehensive upgrade plan.
1.1 Open the Project
- Open the project on the
mainbranch
1.2 Open the App Modernization App Modernization
- Open the GitHub Copilot App Modernization
1.3 Start the Assessment
1.4 Review the Assessment Report
-
A comprehensive assessment report is generated, covering:
- Current state analysis (Java version, Spring Boot version, dependencies)
- Recommended target versions
- Potential breaking changes and blockers
1.5 Review Detailed Findings
Expected Outcome: A clear understanding of the modernization scope, risks, and step-by-step plan before making any code changes.
Objective: Upgrade Java 8 β 21 and Spring Boot 2.7 β 3.3 in incremental, compilable steps.
2.1 Initiate the Upgrade Process
-
Open the GitHub Copilot App Modernization
-
Click Upgrade Java Runtime & Frameworks
-
The agent analyzes the repository β POM files, source code, dependency tree β and proposes target versions
2.2 Review the Upgrade Plan
-
GitHub Copilot App Modernization generates a step-by-step upgrade plan and saves it to
.github/java-upgrade/:plan.md # Full upgrade plan with steps, verification commands, and challenges progress.md # Step-by-step execution log summary.md # Final results and post-upgrade report
2.3 Approve and Execute the Plan
- Review, modify if needed and approve the plan
- The agent executes each step automatically β updating POM files, migrating imports, recompiling, running tests, and committing changes at every milestone
- Each step is verified before proceeding to the next
2.4 Review the Summary
- Once all steps complete and final validation passes, a summary is created at
.github/java-upgrade/summary.md - The summary includes upgrade results, technology stack diff, commit log, CVE scan, and challenges encountered
2.7 Verify the Upgrade
-
Run the following command to confirm the project compiles:
./mvnw clean compile
Expected Outcome: Project compiles with Java 21 and Spring Boot 3.3.7, all javax imports replaced with jakarta.
Objective: Add comprehensive unit tests to validate application behavior post-upgrade and establish a safety net for future changes.
3.1 Generate Unit Tests
-
After the Java 21 / Spring Boot 3.3.7 upgrade completes, GitHub Copilot App Modernization presents a Proceed option
-
Click Generate unit tests to automatically create tests for classes with low or no coverage
3.2 Review the Coverage Analysis
-
A coverage analysis identifies classes with no or insufficient test coverage:
Module Source Files Test Files Gap web 14 classes 0 test files No coverage at all worker 10 classes 2 test files Partial coverage
3.3 Review Generated Tests
- The agent generates JUnit 5 + Mockito tests targeting the most important business-logic classes:
3.4 Verify the Tests
-
Run the test suite and confirm all tests pass:
./mvnw clean testMetric Before After Test files 2 6 Total tests 16 47 Pass rate 100% (16/16) 100% (47/47) Web module tests 0 18 Worker module tests 16 29
Expected Outcome: All tests pass, covering controllers, services, and message processors across both modules.
Objective: Identify and fix security vulnerabilities in project dependencies.
4.1 Trigger CVE Scan
-
Open GitHub Copilot App Modernization
-
Click Scan and Resolve CVEs to trigger a scan of all project dependencies
-
The scan analyzes:
- Direct dependencies declared in each module's
pom.xml - Transitive dependencies resolved through the Spring Boot BOM
- All compile and runtime scope artifacts
- Direct dependencies declared in each module's
4.2 Review the CVE Report
-
The scan identified 16 known vulnerabilities across 4 dependencies:
Dependency Version CVEs Highest Severity org.apache.tomcat.embed:tomcat-embed-core10.1.34 13 CRITICAL com.fasterxml.jackson.core:jackson-core2.17.3 1 HIGH org.springframework.boot:spring-boot3.3.7 1 HIGH org.postgresql:postgresql42.7.4 1 HIGH
4.3 Apply CVE Fixes
-
GitHub Copilot App Modernization resolves all CVEs by upgrading dependency versions in the parent
pom.xml:Change Before After Method Spring Boot parent 3.3.7 3.3.13 Parent POM version bump Tomcat 10.1.34 10.1.52 <tomcat.version>overrideJackson 2.17.3 2.18.6 <jackson-bom.version>overrideNetty 4.1.122.Final 4.1.124.Final <netty.version>overridePostgreSQL 42.7.4 42.7.7 Resolved via Spring Boot 3.3.13 BOM
4.4 Confirm Resolution
- Ask Copilot to generate a full vulnerability assessment report summarizing the CVEs found, their severities, and the fixes applied.
- After applying the changes, a re-scan confirms 0 known vulnerabilities remaining
4.5 Verify the Fix
-
Run the following command to confirm everything compiles and passes:
./mvnw clean verify
Expected Outcome: No critical or high-severity CVEs in dependencies. Assessment report documents all findings and remediations.
Objective: Replace AWS S3 dependencies with Azure Blob Storage, using Azure Identity (Managed Identity / DefaultAzureCredential) for authentication.
5.1 Review Cloud Readiness Tasks
-
In the assessment of the project, check the Cloud readiness tasks
-
The assessment identifies AWS-specific dependencies, configurations, and code patterns that need to be migrated to Azure equivalents
5.2 Execute the task
5.4 Review the Migration Summary
5.5 Verify the Migration
-
Local testing (dev profile β uses local file storage, no Azure account needed):
SPRING_PROFILES_ACTIVE=dev ./mvnw -pl web spring-boot:run
-
Azure testing β requires additional setup before running: Update
application.propertiesin bothwebandworkermodules:azure.storage.account-name=<your-storage-account-name> azure.storage.blob.container=<your-container-name>
Or pass them as environment variables:
AZURE_STORAGE_ACCOUNT_NAME=<your-storage-account-name> \ AZURE_STORAGE_BLOB_CONTAINER=<your-container-name> \ ./mvnw -pl web spring-boot:run
Expected Outcome: All AWS references removed. Application uses Azure Blob Storage with DefaultAzureCredential. Local dev profile provides a file-system fallback for development without any Azure setup.
Objective: Package the application into optimized Docker containers and prepare Azure deployment infrastructure.
6.1 Start Containerization
-
In the assessment of the project, check the Cloud readiness tasks
-
Execute the Containerization task. The assessment includes a containerization task for preparing the application for Docker and cloud deployment
6.2 Review the Containerization Plan
-
The agent generates a containerization plan covering Dockerfiles, Docker Compose, and Azure infrastructure
6.3 Execute the Plan
-
After reviewing and approving the plan, the agent executes each step:
- Creates multi-stage Dockerfiles for
webandworker - Generates
docker-compose.ymlfor the full local stack - Creates Bicep templates for Azure Container Apps
- Generates
azure.yamlfor the Azure Developer CLI
- Creates multi-stage Dockerfiles for
-
Key artifacts generated:
web/Dockerfileβ Multi-stage build with Eclipse Temurin 21, non-root user, health checkworker/Dockerfileβ Multi-stage build for background processingdocker-compose.ymlβ PostgreSQL, RabbitMQ, Web, and Worker servicesinfra/main.bicepβ Azure Container Apps environment, registry, and app definitionsazure.yamlβ Azure Developer CLI deployment configuration
6.4 Build and Test Locally
-
Build and run with Docker Compose:
# Build images docker build -t assets-manager-web:latest -f web/Dockerfile . docker build -t assets-manager-worker:latest -f worker/Dockerfile . # Start all services docker-compose up -d # View logs docker-compose logs -f # Stop docker-compose down
-
Verify the services are running:
Service URL Credentials Web UI http://localhost:8080 β RabbitMQ Management http://localhost:15672 guest/guestPostgreSQL localhost:5432 postgres/postgres
6.5 Deploy to Azure
-
Deploy using the Azure Developer CLI:
# Login azd auth login # Deploy everything (infrastructure + containers) azd up
Expected Outcome: Application deployed to Azure Container Apps with azd up.
Contributions are welcome! This repository is meant to be a learning resource for the community.
- Fork the repository
- Create a feature branch (
git checkout -b feature/improvement) - Make your changes and commit
- Push to your branch and open a Pull Request
- Spring Boot Migration Guide
- Jakarta EE Migration
- Azure SDK for Java
- Azure Container Apps Documentation
- GitHub Copilot Documentation
- Azure Developer CLI (azd)
This project is licensed under the MIT License β see the LICENSE file for details.












