Summary
Your organization can complete application modernization efforts on time, but only if you’re ready. If you have a lot of technical debt, the process will be slower, messier, and more prone to mistakes.
In this post you will learn:
- Technical debt can be dead and unused code, inactive feature flags, and more
- There are tools to help identify technical debt, but they have drawbacks
- Only Azul Intelligence Cloud automatically collects information from the JVM as it runs code in production
Imagine your company’s flagship application runs on JDK 21. As head of engineering, you have until September 2029 to move the application onto JDK 25, or the free support you enjoy will expire. The upgrade from JDK 21 to JDK 25 should be pretty routine, but the stakes are high. There will be a lot of testing, and you don’t want to wait until the last minute.
Now imagine the owner of another application in your company needs to migrate her application from JDK 8 to enable application modernization and to avoid the challenges of unsupported Java. Free support expiries in 2030. You will probably have to upgrade from JDK 8 to JDK 11 before upgrading to more modern Java versions. This will be time-consuming.
It’s doable, but only if your organization is ready. If you have a lot of technical debt, the process will be slower, messier, and more prone to mistakes.
What is technical debt?
Definitions sometimes vary, but an application has technical debt if it has
- Code that was prototyped but never used
- Code that has been superseded but never removed
- Code that’s exercised as part of outdated test routines but never runs in production
- Code that was pulled in as part of an open-source dependency tree but adds no value
- Feature flags that were put in a long time ago but are no longer active
This kind of technical debt is often referred to as “unused and dead code” which makes the creation of new features and functionality slower, more expensive and more prone to unintended consequences. For most organizations, this kind of tech debt acts as a drag on innovation but just finding it (never mind getting rid of it) can be extremely time and resource intensive.
Are there tools on the market for technical debt?
Sure, there are tools to help identify technical debt, but each has significant drawbacks.
- Static code analysis tools – Every development team has a few of these tools they use to scan their codebase and make recommendations to improve security, maintainability and quality of the code. Unfortunately, when it comes to identifying technical debt in general, and unused/dead code specifically, they can only make guesses since they have no access to running code. These guesses err on reachability, making more code look “active.”
- Logging tools – these tools can provide indirect indicators of dead code. For example, you might identify logs that get generated in test environments but DON’T exist in production environments and therefore infer that the process associated with that log is no longer running. But logs are unreliable since not all methods generate logs, and log messages can vary.
- AI tools – these typically take the form of “AI-enhanced” versions of existing tools. When well trained on a diverse set of data, they can provide much better guesses as to which code may be dead or unused. But AI tools are still missing a direct signal of what code is/isn’t used. Without a strong direct signal, they make assumptions similar to static analysis.
Software becomes harder to maintain, more challenging to secure, and more expensive to run.
For SaaS providers and online services platforms, this problem only grows as applications scale. The larger the codebase, the harder it becomes to answer basic questions:
- What code is actually running?
- What code is dead and safe to remove?
- Where is my security risk concentrated?
Isn’t there a tool to directly identify dead and unused code?
Azul Code Inventory, a feature of Azul Intelligence Cloud, automatically collects information from the Java Virtual Machine (JVM) as it runs code in production. It does so for any JVM without imposing operational overhead, and then presents this information in a report so you can instantly identify which libraries, classes and methods of a Java application are present in the codebase but never used in production.
One of the world’s largest online services platforms faced this exact challenge. With thousands of Java workloads across global cloud regions, the company’s engineering teams struggled to manage technical debt at scale. Two critical issues are manually uncovering unused code and finding known vulnerabilities.
Because Intelligence Cloud can run in production with no performance penalty, it took only a few days to identify some serious issues in the company’s Java estate:
| Discovery |
|---|
| Nearly 50% of the customer’s application code went unused. Only 45% of the total JARs in their codebase were used. Engineers spent 10% of their time actively maintaining unused and dead code. Only 47% of vulnerabilities identified were used in production |
Azul Intelligence Cloud dramatically slashes time from unproductive tasks, including maintaining and updating unused and dead code, as well as investigating vulnerability false positives. Working closely with the customer to compare source-commits and vulnerability alerts against code that did not run, Azul identified the potential to recover an incredible amount of lost developer capacity.
| Savings |
|---|
| 24 full-time developer hours from eliminating the maintenance of dead and unused code 6 full-time developer hours from eliminating chasing vulnerability false positives |
Find out more
Knowing which code to remove is one thing. Removing it safely and securely from a codebase is something else. That’s why Azul has created an OpenRewrite plugin to help automate and accelerate Java application modernization efforts by streamlining the removal of unused and dead code.
To learn more about how Azul Intelligence Cloud works, read our new ebook, The Java Application Modernization Crisis.
