Cloud migration for enterprise Java applications is rarely a single decision — it is a series of decisions made across a portfolio of applications with different ages, architectures, business criticality, and team ownership. The '6 Rs' framework (Rehost, Replatform, Repurchase, Refactor, Retire, Retain) provides a useful taxonomy, but enterprise teams need more granular criteria for evaluating which approach is appropriate for each application. This article provides a practical framework for making those decisions, with specific guidance for Java applications running on traditional application servers.
Assessing Your Application Portfolio
Before selecting a migration strategy, teams need an honest assessment of each application's characteristics. The relevant dimensions are: business criticality (what is the cost of downtime or degraded performance?), technical complexity (how many external dependencies, integrations, and custom configurations exist?), team knowledge (does the team that owns the application have the skills to execute the migration?), and migration urgency (is there a data center exit deadline or a cost driver creating time pressure?).
Applications that score high on business criticality and technical complexity warrant the most careful migration planning. A rehost (lift-and-shift) to IaaS may be the appropriate first step, providing a stable foundation from which to modernize incrementally. Applications that are low criticality and technically simple are candidates for more aggressive modernization or retirement.
Inventory the runtime dependencies carefully. Java EE applications running on WebLogic or JBoss may use proprietary APIs — EJBs, JMS implementations, proprietary transaction managers — that have no direct equivalent in cloud-native environments. These dependencies significantly increase migration complexity and should be identified before committing to a migration timeline.
Rehost: When Lift-and-Shift Makes Sense
Rehosting — moving an application to cloud infrastructure without changing its architecture — is often dismissed as not delivering cloud value. This criticism is partially valid but misses the legitimate use cases for rehosting.
For applications with hard data center exit deadlines, rehosting is often the only feasible option. A complex Java EE application with years of accumulated configuration cannot be re-architected in the weeks available before a data center lease expires. Rehosting buys time for a more deliberate modernization effort.
Rehosting also makes sense for applications that are in maintenance mode — receiving only bug fixes and minor enhancements — where the business case for modernization investment is weak. Running these applications on cloud IaaS provides operational benefits (managed infrastructure, better availability) without requiring engineering investment in the application itself.
The key discipline for rehosted applications is to avoid treating the cloud as a more expensive data center. Right-sizing instances, using reserved pricing for predictable workloads, and implementing auto-scaling for variable workloads are essential for realizing cost benefits.
Replatform: Targeted Modernization
Replatforming involves making targeted changes to take advantage of cloud capabilities without fundamentally re-architecting the application. For Java applications, common replatforming moves include migrating from self-managed databases to managed RDS instances, replacing on-premises message brokers with managed services like Amazon MQ or MSK, and containerizing applications for deployment on ECS or EKS.
Containerization is often the highest-value replatforming move for Java applications. Packaging an application as a Docker container, even without changing its internal architecture, provides deployment consistency, simplifies environment management, and enables gradual adoption of container orchestration capabilities.
Spring Boot's embedded server model makes containerization straightforward for applications already using Spring Boot. For applications running on traditional application servers (Tomcat, JBoss, WebLogic), containerizing the application server adds complexity. In these cases, migrating to Spring Boot's embedded server model as part of the replatforming effort often delivers better long-term outcomes.
Refactor: Cloud-Native Re-Architecture
Refactoring — re-architecting applications to be cloud-native — delivers the most cloud value but requires the most investment. For Java applications, this typically means decomposing monoliths into microservices, adopting event-driven patterns with Kafka or SQS, implementing the 12-factor app methodology, and designing for horizontal scaling.
The business case for refactoring must be explicit. Refactoring is justified when the current architecture is a genuine constraint on business agility or system reliability, when the application is strategically important and will receive ongoing investment, and when the team has the skills and capacity to execute the re-architecture without disrupting ongoing feature delivery.
Strangler Fig is the recommended pattern for incremental re-architecture of large monoliths. New functionality is built as separate services, and existing functionality is migrated incrementally. The monolith shrinks over time as functionality is extracted, rather than being replaced in a single high-risk cutover.