RPG to Java Migration

ModernLift · ·13 min read
Part 4 of 9

RPG to Java migration transforms IBM i business logic written in RPG into Java (or C#) running on a modern, cloud-portable stack. Done well it is a genuine transformation into maintainable domain services, not a literal line-by-line conversion — and it is paired with migrating the data off DB2 for i and recovering the business rules the RPG enforces. The hard part is not the syntax; it is preserving decades of undocumented, load-bearing behavior, which is why every slice is proven at parity against the running AS/400 before it carries live traffic.

Part 3 drew the line between modernizing RPG in place and moving it off the platform entirely. This part takes the off-platform path seriously: transforming RPG into Java or C# on a modern, cloud-portable stack. It is the option buyers ask about most by name — “we want to get off RPG and onto Java” — and the one where the gap between the sales demo and the production reality is widest. The goal here is to show what real transformation involves, why the business rules are the actual difficulty, and how the work is kept honest.

Why move RPG off the platform at all

First, the honest qualifier carried from Part 1: you do not have to. IBM i is supported, and for many shops the in-place modernization from Part 3 is the better-value answer. Moving RPG to Java is warranted when there is a specific reason the platform itself has to go:

  • Platform independence and cloud portability. The business wants its core logic running on infrastructure it can choose and change, not tied to Power hardware and IBM i licensing.
  • A unified technology stack. An organization standardizing on Java or .NET across its estate does not want one critical system on a language nobody else writes.
  • An architecture the AS/400 cannot accommodate. Event-driven processing, a particular cloud-native data platform, or an integration model that does not fit the IBM i runtime.
  • Skills strategy. Hiring Java or C# developers is straightforward; hiring RPG developers is the shrinking-pool problem from Part 2. Moving to a mainstream language permanently solves the hireability problem.

If none of these apply, the in-place path is usually cheaper and lower-risk. Where they do apply, the migration is worth doing well — which is the rest of this article.

Transformation versus translation

The single most important distinction in this work is between translation and transformation, and the budget difference between getting it right and wrong is enormous.

Translation is mechanical: take the RPG, produce Java that does the same thing line by line. Tools do this, and the output compiles. But RPG and Java have fundamentally different shapes. RPG programs are often monolithic, built around global data and (in older dialects) a fixed program cycle, with logic and database access intermingled. Translate that literally and you get Java that preserves all of it — a giant class full of global state and procedural flow, decorated with Java syntax. It runs. It is also “RPG written in Java”: legacy code wearing a modern costume, frequently harder to maintain than the original because it has lost the platform idioms that at least made the RPG coherent.

Transformation is architectural: understand what the RPG does — the business capabilities, the rules, the data it owns — and rebuild that as idiomatic, modular Java domain services with proper separation of logic and data access, real tests, and clean interfaces. The output is judged by whether a Java developer who has never seen RPG can maintain it. That is the only end state worth paying for, and it cannot be produced by a tool running unattended, because the reshaping requires architectural judgment about boundaries the original code never expressed.

Automation still has a large role — it accelerates the reading and drafts the translation — but as an accelerator under senior-engineer review, never as the decision-maker. The translation is the easy fraction of the work; turning it into maintainable services and proving it correct is the rest.

Java or C#? The decision that matters less than it seems

Teams spend disproportionate energy on the target-language choice. Both Java and C#/.NET are excellent, mature targets for RPG business logic. The right choice follows from your context, not from any inherent superiority:

  • A shop already invested in the Microsoft ecosystem — Windows, SQL Server, Azure, .NET elsewhere — will usually land on C#/.NET.
  • A shop standardized on the JVM, or targeting a particular cloud-native or open-source ecosystem, will usually land on Java.

What matters is that the decision is made for ecosystem-fit reasons and then gotten out of the way, because the genuinely hard and consequential decisions — recovering the rules, slicing the work, proving parity — are identical no matter which modern language you choose.

The hard part: the rules the RPG enforces

Here is where RPG-to-Java migrations actually fail, and it has nothing to do with syntax. Decades of RPG accumulate enforced business rules that live nowhere but the code:

  • The rounding convention applied to a tax or interest figure, consistent across the system because one shared routine enforces it.
  • The special handling for a customer class, product type, or transaction code added years ago for a reason no one remembers but that downstream processing still depends on.
  • The exact order in which steps in a calculation or a batch run must occur, because a later step assumes the state a previous one left behind.
  • The validation that silently rejects or transforms certain inputs — rules users have unknowingly relied on for years.

These are not documented. They are not in comments. They are the behavior the business has quietly depended on, and they are the tribal knowledge that walks out the door with the retiring developers. A migration that faithfully translates the visible logic but misses these rules produces software that looks correct and is subtly, dangerously wrong — and because the AS/400 often runs money and compliance-sensitive workloads, “subtly wrong” is not a cosmetic defect; it is a financial or regulatory event surfacing weeks after cutover as a “regression”.

This is why discovery — recovering the rules as living specs from the actual RPG, DB2 and CL — is not preamble to the migration. It is the migration’s foundation. Skip it, or do it from memory, and you are translating code without knowing what it is supposed to do.

Keeping it honest: parity validation

You cannot prove an RPG-to-Java migration is correct by code review — no one can read both well enough, and the rules are not all written down to check against. You prove it by behavior. Parity validation is the discipline that does this:

  1. The rebuilt Java slice runs in the shadow of the AS/400 — fed mirrored production inputs, carrying no live load yet.
  2. Its outputs are compared against the AS/400’s, transaction by transaction, including the edge cases and the awkward inputs, through output reconciliation.
  3. Discrepancies are investigated — each one is either a bug in the new code or a previously unknown business rule the old system was enforcing. Both are valuable findings; the second is how you discover the rules nobody documented.
  4. The slice carries live traffic only after it has been proven to behave identically, and a rollback path stays available.

This is the difference between migrating on evidence and migrating on hope. On a system running the order-to-cash core, that distinction is the entire safety case.

Slice by slice, never big-bang

Everything above is delivered incrementally, the same principle that runs through the whole field. The RPG estate is sliced by business capability — a pricing engine, an order workflow, a billing calculation — and each slice is recovered, rebuilt, proven at parity, and cut over behind a facade while the AS/400 keeps running everything not yet migrated. A big-bang RPG-to-Java rewrite that cuts the whole core over on a date concentrates all the risk into one irreversible moment and tries to rediscover every undocumented rule at once. It is the archetype of the programs that fail (BCG, 2023). Incremental delivery converts that single bet into a series of small, reversible, proven steps — and starts returning value after the first slice rather than after a distant cutover.

Where this leads

RPG-to-Java migration moves the logic, but logic is only half the system. The RPG depends on data — and on the AS/400 that data lives in DB2 for i, often defined in legacy DDS, with integrity rules enforced by the database itself. Migrating the logic without correctly migrating the data, and the constraints the data carries, is how a clean transformation still produces a broken system. Part 5, DB2 for i Migration, covers moving the data off the integrated database — schema recovery, integrity preservation, and why the database’s enforced rules are as load-bearing as the RPG’s.

Frequently asked questions

Can RPG be automatically converted to Java?
Mechanically, yes — tools can translate RPG into Java that compiles. The problem is what you get: unattended conversion preserves the legacy program structure, the global data, and the procedural flow, producing "RPG written in Java" that runs but is no more maintainable than the original. Useful transformation uses automation as an accelerator under senior-engineer review, reshaping the drafted output into idiomatic, testable domain services. The translation is the easy 20%; turning it into code worth maintaining, and proving it behaves identically, is the rest.
Should we migrate RPG to Java or to C#/.NET?
Both are sound targets; the choice should follow your organization's existing skills, platform strategy, and surrounding ecosystem rather than any inherent superiority. A shop already invested in the Microsoft stack will usually choose C#/.NET; one standardized on the JVM or targeting a particular cloud-native ecosystem will choose Java. The harder and more consequential decisions — how to recover the business rules, how to slice the migration, how to prove parity — are identical regardless of which modern language you land on.
What is the biggest risk in an RPG-to-Java migration?
Silently losing business rules. Decades of RPG encode undocumented behavior — rounding conventions, edge-case handling, the exact sequence a calculation runs in — that exists nowhere but the code. A migration that translates the obvious logic but misses these rules produces software that looks right and is subtly wrong, and the errors surface as "regressions" after cutover, often in money or compliance-sensitive places. The mitigation is recovering the rules as living specs during discovery and proving equivalence through parity validation before any slice carries live traffic.
All 9 parts of AS/400 & IBM i (RPG) Modernization →