IBM Bob

Java Modernization: Making Enterprise Upgrades Tractable

Upgrade your enterprise Java apps from stuck to modern with guided, agentic workflows.

Java Modernization: Making Enterprise Upgrades Tractable

Authors

Jay TalekarBrian Taylor

Published

Category

announcement

Share

Java Modernization: Making Enterprise Upgrades Tractable

Walk into any large enterprise — a bank, an airline, a telecom — and Java is usually doing the heavy lifting. Core banking systems, fraud detection pipelines, order management, overnight batch jobs that reconcile millions of transactions before sunrise. It works, it scales, and that is precisely why so much of it is still running on Java 8, or older.

Working is not the same as healthy. Frameworks sit on versions that no longer receive security patches. The original authors are long gone. "Don't touch it, it works" has hardened into an architectural principle. And the gap keeps widening: records, sealed classes, pattern matching, virtual threads, the G1/ZGC collectors, better container awareness, and faster startup are all sitting on the other side of an upgrade nobody wants to schedule.

This post is about closing that gap. It covers why these applications get stuck, then walks through the five capabilities in the Premium Package for Java — JDK version upgrades, Liberty re-platforming, UI modernization, unit test generation, and security remediation — and how each splits the work between deterministic automation and AI. It closes with what your repository needs in place to get the most out of them, how to get access, and how to start.

Why so many Java apps are stuck a decade behind

If modernization is so obviously worthwhile, why do so many enterprise Java applications still look frozen around 2014? The causes are structural: organizational gravity and genuine engineering risk.

  • Organic growth, not designed growth. These systems grew feature by feature, acquisition by acquisition. Layers of code piled on older layers, each written under different deadlines and conventions. What you inherit today resembles geological sediment: decisions made by dozens of teams over a decade.
  • The engineers who wrote the core modules have moved on, and the tribal knowledge left with them. What remains is sparse documentation and a few senior engineers who "kind of remember how that module works."
  • Upgrading Java means dependency audits, framework upgrades (Spring, Hibernate, Jakarta EE namespace migrations), removal of deprecated APIs, and revalidation across every environment — months of effort, real budget, and real opportunity cost, hard to justify when the system already works.
  • Even a Java 8 → 17 or 21 jump can surface module-system conflicts, removed internal APIs (sun.misc.Unsafe), reflection warnings turning into hard errors, and subtle garbage-collector behavior changes. A version bump on paper becomes a multi-week investigation in practice.
  • Regression cycles are long. Sprawling test suites — unit, integration, performance, UAT, sometimes manual sign-offs — mean a single upgrade can trigger weeks of testing before it ships.
  • Underneath all of it: fear of breaking what works. When an application moves millions of dollars a day, the cost of a bad deploy dwarfs the cost of not upgrading, so the upgrade conversation slides to next quarter. And the quarter after that.

The way out is incremental, not a rewrite. With the right tooling, you can pay the debt down in steps small enough that each one is safe to ship.

The Premium Package for Java

The Premium Package for Java is a suite of five workflows for enterprise Java modernization. Each is built on the same division of labor: let deterministic automation do the predictable, mechanical work, and let AI handle the contextual decisions that recipes can't encode.

Rule-based engines like OpenRewrite are reliable at mechanical refactoring across thousands of files. AI is better at the messy parts — interpreting build errors, reasoning about business logic, choosing between trade-offs. Bob orchestrates both in a stepwise workflow with a human approving the consequential steps.

The expertise behind it matters here. The workflows are shaped by engineers from IBM and Red Hat who built JIT compilers, shipped WebSphere and Open Liberty, helped pioneer Quarkus, and contributed to OpenJDK, Jakarta EE, and MicroProfile. The tooling encodes how those teams approach a migration — knowledge a model cannot reconstruct from the code in front of it.

Here is how the split plays out across the five capabilities.

Capability 1: JDK version upgrades — Java 8 to 11, 17, 21, or 25

Upgrading the JDK is the most common modernization task and the most underestimated. Bob treats it as a multi-stage, evidence-driven journey rather than a single command.

  • Project intelligence first. Bob analyzes the build tool (Maven or Gradle), module topology, current Java version, and framework footprint, then proposes viable upgrade paths (8→17, 8→21, with or without Jakarta EE), each annotated with a difficulty rating and the technical challenges to expect.
  • For the chosen target, curated OpenRewrite recipes handle the mechanical transformations safely and at scale.
  • Recipes get you part of the way; in practice, 40–50%. The rest — exotic dependency conflicts, removed internal APIs, library-specific breakage — is where the agentic loop kicks in. Bob compiles the project, parses the Maven/Gradle build logs, groups exceptions by root cause, and asks the AI for targeted fixes, module by module.
  • Guardrails that respect intent. The AI is instructed never to silently switch between javax and jakarta namespaces, never to comment out code or relocate files to "make it compile," and to request explicit approval before any package or dependency change.

You get an upgrade that is fast where it can be automated and careful where it can't, with a full audit trail at the end.

Capability 2: Liberty re-platforming — traditional WebSphere to Liberty

Migrating from traditional WebSphere Application Server to WebSphere Liberty or Open Liberty buys you a lower memory footprint, container-friendly packaging, faster startup, and modern Jakarta EE support. It is also one of the most intricate migrations to attempt by hand.

  • AMA-driven assessment. Bob ingests output from IBM's Application Modernization Accelerator, parsing its reports into specific, file-level migration issues with rule-based remediation guidance.
  • Each AMA rule carries prescriptive guidance — "replace com.ibm.websphere.* with the Jakarta EE standard equivalent," "migrate ibm-web-ext.xml configuration to server.xml." Bob feeds these issues, grouped by root cause, to the AI along with the rule's help text, so the model applies the known fix instead of guessing.
  • Where the migration involves a Jakarta jump, the same OpenRewrite recipe library handles the namespace mechanics deterministically.
  • Build, deploy, verify. Bob builds the WAR/EAR, deploys via liberty-maven-plugin or liberty-gradle-plugin, tails server logs for startup and class-loading failures, and resolves them iteratively. Functional verification with curl against REST endpoints is part of the standard flow.

The workflow encodes how Liberty engineers approach the migration, rather than leaving it to a generic prompt.

Capability 3: UI modernization — JSP/Struts to a modern SPA

Most legacy Java apps still drive their UIs through JSP, Struts, or servlets. Bob splits this into a five-phase pipeline.

  • Architecture extraction. Before any code is rewritten, Bob analyzes the application and produces an architecture.md cataloging every controller, action, servlet, page, form, validation rule, and data-flow path. That document is the source of truth for the rest of the migration.
  • The legacy presentation layer (Struts actions, servlets, JSP controllers) is converted into REST endpoints on a modern backend — Spring Boot, Quarkus, or Liberty — with the original DAOs and model classes left untouched to protect database integrity.
  • Frontend scaffolding. A new TypeScript project (Angular, React, or another framework) is wired to a chosen design system — Carbon, Material UI, or shadcn/ui — with HTTP client, theming, routing, state management, error boundaries, and CORS set up before any feature work begins.
  • JSP forms and tables are then mapped to design-system equivalents — DataTables, Cards, DatePickers, validated Forms — with the original business rules carried forward.
  • Validation gates at every step. Bob never starts the application itself. After each phase it asks the developer to run the build/start command and confirm, keeping verification in human hands.

AI handles the contextual translation from JSP tag soup to modern components; automation handles the scaffolding, dependencies, and build verification.

Capability 4: Unit testing — strategy first, then generation

Test coverage is often the single biggest blocker to modernization: you can't safely upgrade what you can't safely verify. Bob generates a testing strategy before it generates tests.

  • Strategy generation. Bob analyzes the project and produces a UNITTEST.md covering architecture, modules that need coverage, recommended frameworks (JUnit 5, Mockito, AssertJ), naming conventions, coverage thresholds, and the exact commands to run tests with and without coverage reporting.
  • Candidate selection works at multiple granularities — entire packages, specific classes, individual methods — and can run off git diffs to focus effort on recently changed code.
  • Generate, run, fix. Every test prompt ends with the same instruction: run the tests, fix the failures. The AI executes, observes failures, and iterates until the suite is green rather than stopping at code generation.
  • Bob integrates with JaCoCo so the loop targets measured coverage rather than a green test run alone.

Automation runs the tests; AI writes them and reasons about the failures. The coverage that results is what unblocks the other four workflows.

Capability 5: Security remediation — CVEs as part of the same loop

A modernized application still shipping CVE-laden dependencies is only half done. Security remediation reuses the same architecture as the JDK upgrade, pointed at vulnerabilities.

  • Build-driven detection. Bob reuses the Maven and Gradle log analyzers from the upgrade workflow, tuned to surface dependency advisories, deprecation warnings, and known-vulnerable transitive dependencies from build output, dependency-check plugins, and SBOM tools.
  • When a fix isn't a clean version bump — say, the patched library changed signatures and the call sites need migrating — the agentic loop groups the breakages by root cause, applies the remediation across modules, and rebuilds to verify.
  • The same guardrails apply. No dependency changes without explicit approval, no commented-out code, no namespace surprises. Fixes are surfaced, explained, and confirmed before they land.

Security hardening runs on the same track as the rest of the modernization work rather than as a separate roadmap.

The common thread

Across all five capabilities, the same division of labor holds:

PhaseOwner
Project analysis & metadata extractionAutomation
Mechanical, well-known transformationsOpenRewrite recipes
Build, log parsing, error groupingAutomation
Contextual decisions, error remediation, code translationAI
Approval gates, verification, deploymentHuman-in-the-loop
Audit trail (Mermaid diagrams, task summaries, cost tracking)Automation

Automation handles what is deterministic, AI handles what is contextual, and a human approves what is consequential — backed by the IBM and Red Hat engineers who built the platform underneath it.

Make your repository ready

These workflows go further on a codebase that is already legible — and the things that help Bob are the same things that help any engineer inheriting the code:

  • A green, reasonably fast build. Every loop here is anchored to compile and test output. The faster and more reliable your mvn/gradle build, the tighter the generate-run-fix cycle.
  • Existing tests, even partial. Coverage is both a safety net for upgrades and a signal Bob reads. If you have little of it, start with Capability 4 before attempting a version jump.
  • A pinned, declared dependency tree. Clear pom.xml/build.gradle versions and a current dependency lock make the difference between a clean recipe run and a multi-day conflict hunt.
  • Build tooling Bob can drive. The Liberty and security workflows lean on standard plugins (liberty-maven-plugin, dependency-check, SBOM tooling); having them wired up lets the automation half do its job.

How to get access

The Premium Package for Java is an add-on to a Bob base plan, not a separate download.

How you get entitled depends on your plan:

  • Individual plans (Pro, Pro+, Ultra). Go to the pricing page on bob.ibm.com, choose a plan, and add the Java add-on during checkout. After you complete the order and install the Bob IDE, the entitlement is detected on login. You manage seats and add-ons from your subscription at bob.ibm.com.
  • Enterprise plans. Your Bob administrator assigns base-plan seats and the Java add-on from the Bob Admin UI. Once a seat is assigned to you, the same automatic detection applies — log in and the workflows appear.

Two things worth being explicit about:

  • You have to select the Java add-on at checkout. It is not part of the base plan by default. If you skip it during purchase, the workflows won't show up, even on a paid plan.
  • Trial plans can't use add-ons. The Premium Package for Java requires a paid Pro, Pro+, Ultra, or enterprise plan.

Get started

Once your plan includes the add-on and you're signed in to the Bob IDE:

  • Run the JDK upgrade assessment on a single module first to see the proposed paths and difficulty ratings before committing to a target.
  • If coverage is thin, generate a UNITTEST.md strategy and build a safety net before any version jump.
  • Approve changes module by module — the guardrails are there to keep namespace and dependency changes in your hands.

See the case studies at bob.ibm.com for how teams have run these migrations end to end.