When Java Enterprise Edition (Java EE) hit the scene in the late 1990s, it was a welcome enterprise-class extension of the explosively popular Java language. J2EE (Java 2 Enterprise Edition, as it was called then) extended Java’s ‘write once, run anywhere’ promise to n-tier architectures, offering Session and Enterprise JavaBeans (EJBs) on the back end, Servlets on the web server, and Java Server Pages (JSPs) for dynamically building HTML-based web pages.
Today more than two decades later, massive quantities of Java EE code remain in production – only now it is all legacy, burdened with technical debt as technologies and best practices advance over time.
The encapsulated, modular object orientation of Java broke up the monolithic procedural code of languages that preceded it. Today, it’s the Java EE applications themselves that we consider monolithic, fraught with internal dependencies and complex inheritance hierarchies that add to their technical debt.
Modernizing these legacy Java EE monoliths, however, is a greater challenge than people expected. Simply getting their heads around the internal complexity of such applications is a Herculean task, let alone refactoring them.
For many organizations, throwing time, human effort, and money at the problem shows little to no progress, as they reach a point where some aspect of the modernization project stymies them, and progress grinds to a halt.
Don’t let technical debt stymie your Java EE modernization initiative. Here’s how to overcome the roadblocks.
Two Examples of Java EE Technical Debt Roadblocks
A Fortune 100 government-sponsored bank struggled with several legacy Java EE applications, the largest of which was a 20-year-old monolith that contained over 10,000 classes representing 8 million lines of code.
Replacing – or even temporarily turning off – this mission-critical app was impossible. Furthermore, years of effort on analysis in attempts to untangle the complex internal interdependencies went basically nowhere.
The second example, a Fortune 500 financial information and ratings firm, faced the modernization of many legacy Java EE applications. The company made progress with their modernization initiative, shifting from Oracle WebLogic to Tomcat, eliminating EJBs, and upgrading to Java 8.
What stymied this company, however, was its dependence on Apache Struts 1, an open-source web application framework that reached end-of-life in 2013.
This aging framework supported most of their Java EE applications, despite introducing potential compatibility, security, and maintenance issues for the company’s legacy applications.
Boiling Down the Problem
In both situations, the core roadblock to progress with these respective modernization initiatives was complexity – either the complexity inherent in a massive monolithic application or in the complex interdependencies among numerous applications that depended on an obsolete framework.
Obscurity, however, wasn’t the problem: both organizations had all the data they required about the inner workings of their Java EE applications. Both companies had their respective source code, and Java’s built-in introspection capabilities gave them all the data they required about how the applications would run in production.
In both cases, there was simply too much information for people to understand how best to modernize their respective applications. They needed a better approach to making decisions based upon large quantities of data. The answer: artificial intelligence (AI).
Breaking Down the Roadblocks
When such data sets are available, AI is able to discern patterns where humans get lost in the noise. By leveraging AI-based analysis tooling from vFunction, both organizations got a handle on their respective complexity, giving them a clear roadmap for resolving interdependencies and refactoring legacy Java EE code.
The Fortune 100 bank’s multi-phase approach to Java EE modernization included automated complexity analysis, AI-driven static and dynamic analysis of running code, and refactoring recommendations that included the automated extraction of services into human-readable JSON-formatted specification files.
The Fortune 500 financial information firm leveraged vFunction to define new service boundaries and a common shared library. It then merged and consolidated several services, removing the legacy Struts 1 dependency in favor of a modern Spring REST controller. It also converted numerous Java EE dependencies to Spring Boot, a modern, cloud native Java framework.
The Business Challenges of Technical Debt
Both organizations were in a ‘for want of a nail, the kingdom is lost’ situation – what seems like a relatively straightforward issue stymied their respective strategic modernization efforts.
When such a roadblock presents itself, then all estimates about how long the modernization will take and how much it will cost go out the window. Progress may stop, but the modernization meter keeps running, as the initiative shows less and less value to the organization as the team continues to beat their head against a wall.
Not only does morale suffer under such circumstances, but the technical debt continues to accrue as well. In both situations, the legacy apps were mission-critical, and thus had to keep working. Even though the modernization efforts had stalled, the respective teams were still responsible for maintaining the legacy apps – thus making the problem worse over time.
The Intellyx Take
During the planning stages of any modernization initiative, the teams had hammered out reasonable estimates for cost, time, and resource requirements. Such estimates were invariably on the low side – and when a roadblock stops progress, the management team must discard such estimates entirely.
Setting the appropriate expectations with stakeholders, therefore, is fraught with challenges, especially when those stakeholders are skeptical to begin with. Unless the modernization team takes an entirely different approach – say, leveraging AI-based analysis to unravel previously intractable complexity – stakeholders are unlikely to support further modernization efforts.
It’s important to note the role that vFunction played. It didn’t wave a magic wand, converting legacy code to modern microservices. Rather, it processed and interpreted the data each organization had available (both static and dynamic), leveraging AI to discern the important patterns in those data necessary to make the appropriate decisions that resulted in timely modernization results. Considering the deep challenges these customers faced, such results felt like magic in the end.