Mainframe Path Start learning free
Applied11 min readLesson 3 of 3

Refactoring COBOL safely and COBOL-to-Java risks

Refactoring changes how code is organised without changing what it does. Do it safely by capturing current behaviour in tests first, then making small changes: splitting large programs, sharing copybooks and removing code you have proven is dead. Converting COBOL to Java is a bigger step with specific risks.

Tests come first

Old programs rarely have automated tests, and their specification is often out of date. Before changing anything, write characterization tests: tests that record what the program does now, including odd behaviour, rather than what someone thinks it should do. If a refactor changes an output, the test fails and you investigate before production finds it.

Modularising

Many critical programs are thousands of lines long with deeply nested logic. Safe steps, each followed by a test run:

  1. Give paragraphs meaningful names and remove GO TO jumps where the flow can be expressed with PERFORM.
  2. Move repeated record layouts into shared copybooks so every program uses the same definition.
  3. Extract a well-bounded piece of logic, such as interest calculation, into a separate subprogram that is CALLed with a clear LINKAGE SECTION interface.
  4. Separate business logic from input and output, so the same rule can be called from batch, CICS or an API.

Removing dead code

Dead code is code that can never run, or that no longer has any caller. It costs effort every time someone reads, tests or converts it. Static analysis can show paragraphs with no path to them and programs with no caller. But dynamic calls (a program name held in a variable), scheduler definitions and rarely-run jobs can hide real use, so confirm with runtime evidence collected over a full business cycle, including month-end and year-end, before deleting.

Static analysis summary (illustrative)
Program  ACCT0400   Lines 6,812
  Paragraphs never referenced ....... 23
  Copybooks included, unused ........ 4
  Dynamic CALL targets (unresolved) . 2   (WS-PGM-NAME)
  Last executed (runtime data) ...... month-end only

The two unresolved dynamic calls above are the warning sign: until you know which program names reach WS-PGM-NAME, you cannot say the candidates are really dead.

COBOL-to-Java: concepts

Conversion approaches range from automated line-by-line translation (fast, but the result often reads like COBOL written in Java) to re-engineering a function in idiomatic Java using the COBOL as a reference. Several vendors offer conversion tooling, and AI-assisted tools (for example IBM watsonx Code Assistant for Z) can suggest Java for selected services. All of them need human review and full regression testing. Java can also run on z/OS itself, close to the data, where it is eligible to run on zIIP processors.

COBOL featureRisk in Java
Packed decimal money fieldsUsing double introduces rounding errors; use exact decimal types such as BigDecimal with explicit rounding rules
Truncation on MOVE to a shorter PICJava does not truncate silently; results differ unless rules are reproduced
REDEFINESOne storage area seen several ways has no direct equivalent; needs careful mapping
EBCDIC collating sequenceSorting and comparisons give a different order in Java strings
Fixed record files and VSAMNeed equivalent access logic or a data migration
CICS and DB2 callsMust be replaced or bridged; transaction boundaries must be preserved
TRY IT YOURSELF

A COBOL field is PIC S9(5) COMP-3. How many bytes does it occupy?

Show a hint

Two digits per byte, plus half a byte for the sign.

Show the solution

5 digits plus a sign nibble is 6 nibbles, which is 3 bytes.

Common mistakes

Refactoring without a baseline

Without tests that capture current behaviour you cannot prove nothing changed. Build characterization tests first.

Deleting code that looks unused

Dynamic calls and month-end or year-end jobs hide real use. Confirm with runtime evidence over a full business cycle.

Using floating point for converted money fields

COBOL decimal arithmetic is exact. Use exact decimal types and reproduce the original intermediate precision and rounding.

What you will see at work

Key terms

Check your understanding.
Take this lesson's quiz and save your progress. Free.

Take the lesson quiz
← Strangler fig, APIs first and event-driven integrationBack to COBOL refactoring and incremental modernization