Skip to main content

Behind Salesforce’s JDK 11 to JDK 17 Migration: Lessons for Modernizing Large-Scale Java Applications

Sankar Rao Bhogi
Jan 13 - 6 min read

In our “Engineering Energizers” Q&A series, we explore the journeys of engineering teams driving innovation. Today, we spotlight Sankar Rao Bhogi, Director of Software Engineering at Salesforce, and his agile and elite JDK Team. This small but highly skilled group led the challenging migration from JDK 11 to JDK 17, a critical upgrade that ensures the performance and scalability of Salesforce’s core applications, including Sales Cloud, Service Cloud, and Marketing Cloud.

Dive into how the team overcame encapsulation challenges and breaking changes, managed the dual transformation of upgrading the build system alongside the migration, and ensured backward compatibility—all while maintaining operational stability and paving the way for future advancements.

What is your team’s mission, and how does it relate to the Salesforce platform?

Our JDK Team is dedicated to ensuring a secure, optimized Java runtime environment for Salesforce. This involves supporting applications like Sales Cloud, Service Cloud, and Marketing Cloud while maintaining the platform’s performance and scalability. By focusing on runtime compatibility and modernization, our mission aligns with Salesforce’s commitment to reliability and innovation.

A critical aspect of our mission was leading the migration from JDK 11 to JDK 17, a foundational upgrade that enabled compatibility with modern frameworks and prepared the platform for future technological advancements. This migration impacted key components across the Salesforce ecosystem and required collaboration across teams to ensure success.

Beyond this effort, we handle dependencies, manage runtime optimizations, and ensure the platform’s security as it scales. Our work provides a critical backbone for developers, empowering them to deliver cutting-edge solutions for customers worldwide.

Sankar explains how Salesforce uses a minimum viable product and continuous improvement to drive innovation.

Why was migrating from JDK 11 to JDK 17 such a significant undertaking for Salesforce?

The migration from JDK 11 to JDK 17 was crucial for enabling compatibility with modern frameworks like Spring 6 and unlocking future innovations. Without this upgrade, Salesforce applications would face limitations, jeopardizing performance and scalability.

What made the migration uniquely challenging was the scale of Salesforce’s Core platform, which is 15GB — significantly larger than most operating systems (around 1GB). Adapting such a vast, metadata-driven ecosystem required extensive testing, validation, and dependency updates. The team had to balance ongoing operations while modernizing the platform, a task that demanded precision and collaboration.

By completing the migration, Salesforce not only ensured its applications remain competitive but also laid the groundwork for faster future transitions. Ultimately, this effort highlighted the team’s ability to manage large-scale system changes efficiently and reinforced Salesforce’s position as an innovator in enterprise technology.

What complexities arose from integrating new dependencies and adapting to breaking changes in JDK 17?

The encapsulation changes in JDK 17 restricted access to internal APIs, impacting components like the Apex runtime and big data pipelines. Libraries such as Byte Buddy and Mockito had to be updated to maintain functionality.

Testing and validation were crucial in resolving these issues. Over 5,000 to 10,000 tests were updated or rewritten to ensure compatibility with the new runtime. Each dependency presented unique challenges, and the team worked closely with partner teams to align updates across the platform. This included validating interdependencies to prevent cascading failures.

How did your team overcome the challenge of maintaining operations while performing the migration?

Maintaining uninterrupted operations during the migration was critical, given Salesforce’s extensive developer base and live applications. To address this, the team implemented parallel infrastructure, allowing JDK 11 and JDK 17 to coexist throughout development and testing. This strategy minimized disruptions to ongoing development.

The migration process involved categorizing changes into incremental and disruptive modifications. Incremental updates were rolled out systematically, while disruptive changes were isolated and rigorously tested in controlled environments. Multiple CI/CD pipelines supported this process, enabling continuous validation and scalability.

Collaboration was also a key factor. By engaging partner teams early in the process, the team mitigated risks and ensured compatibility across Salesforce’s ecosystem. This approach not only preserved operations but also set a standard for handling large-scale migrations with minimal impact on productivity.

How did you ensure backward compatibility while transitioning from JDK 11 to JDK 17?

Ensuring backward compatibility was essential to maintain trust and stability during the migration. The team established a robust fallback mechanism that allowed the platform to revert to JDK 11 if critical issues arose, safeguarding developer workflows and customer applications.

Extensive regression testing was a cornerstone of this strategy. Partner teams collaborated to validate dependencies and ensure no functionality was compromised. The team deployed parallel production environments, simulating real-world conditions to identify and resolve issues early in the process.

This approach balanced innovation with reliability, enabling developers to adopt JDK 17 confidently. By prioritizing backward compatibility, the team reinforced Salesforce’s commitment to trust while delivering a transformative upgrade. The migration ultimately showcased how methodical planning and rigorous testing can mitigate risks in large-scale system transitions.

What specific strategies did you use to ensure that updates in one area didn’t compromise other parts of the platform?

To ensure stability across the platform, the team adopted a phased migration strategy. Runtime and compilation changes were implemented in separate stages, each thoroughly tested before integration. This approach minimized the risk of cross-component failures.

Testing frameworks were expanded to cover platform-wide dependencies, simulating production-like workloads. By leveraging incremental CI/CD pipeline rollouts, the team identified potential issues early and resolved them before scaling updates. This step-by-step process ensured changes in one area didn’t negatively impact others.

Collaboration was equally crucial. Partner teams were engaged to validate dependencies and address potential conflicts. Clear communication and synchronized efforts enabled seamless updates across Salesforce’s complex ecosystem. By balancing thorough testing with incremental rollouts, the team maintained platform integrity while delivering significant improvements.

How did your team address the dual challenge of upgrading the build system from Maven/Ant to Bazel while migrating the core application?

Upgrading the build system from Maven/Ant to Bazel while migrating to JDK 17 presented unique challenges. Bazel introduced a new dependency resolution system, which impacted workflows tied to JDK 11. Simultaneously, the encapsulation changes in JDK 17 required updates to core platform components.

To manage these challenges, the team maintained separate environments for Bazel integration and JDK migration. Continuous validation ensured that changes in one system didn’t disrupt the other. Parallel CI/CD pipelines were instrumental in testing both systems simultaneously, enabling early detection and resolution of issues.

This monumental effort was led by a core team of five engineers, who collaborated across teams to ensure the dual transformation succeeded. Their efficiency not only modernized the build system but also enhanced the platform’s scalability and stability, preparing Salesforce for future advancements.

Sankar explains that innovation comes from tackling everyday problems with new approaches.

How did the migration improve performance and future readiness for Salesforce applications?

The migration to JDK 17 delivered significant performance improvements, enabling faster processing and reducing technical debt. These gains unlocked new capabilities, such as compatibility with frameworks like Spring 6, which are essential for modern application development.

One of the most impactful outcomes was the reduction in the timeline for future upgrades. The migration from JDK 11 to JDK 17 spanned three years, with seven months of active development. However, lessons learned during this process will allow future migrations, like JDK 21, to be completed in just one year.

The migration also enhanced the developer experience, streamlining workflows and enabling more efficient application builds. By addressing immediate challenges and preparing for future innovations, the team ensured that Salesforce applications remain reliable, performant, and ready to meet evolving customer demands.

Learn more

Related Articles

View all