IBM Z and LinuxONE - IBM Z

IBM Z

The enterprise platform for mission-critical applications brings next-level data privacy, security, and resiliency to your hybrid multicloud.


#Servers
#IBMZ
#Enterpriseserver
 View Only

Eliminating "JOBOL": Using AI for Semantic Decomposition into Domain-Driven Microservices

By Everest Kwok posted 22 days ago

  

If you look at the marketing material for many automated modernization tools, the promise sounds effortless: “Drop your legacy COBOL or RPG into our engine, and get cloud-native Java or Go instantly.”

As someone who has spent two decades navigating complex enterprise software pipelines, I can tell you exactly what happens when you run a massive, stateful card processing monolith through a line-by-line translator. You don’t get a modern, scalable cloud application. You get "JOBOL"—procedural, monolithic COBOL logic wrapped awkwardly in a .java syntax file.

JOBOL is the worst of both worlds. It retains all the rigid technical debt, implicit global states, and unmaintainable execution flows of the 40-year-old application, but strips away the raw execution speed native to the mainframe. The developers tasked with maintaining it can’t read it, and the original mainframe engineers don't recognize it.

True modernization requires an architectural shift, not just a syntax swap. To break free from the JOBOL trap, I stop treating Large Language Models as automated transpilers and start treating them as software architects. The key is shifting the objective from code translation to semantic decomposition.

Shifting the AI’s Objective Function

Line-by-line translation fails because legacy codebases tightly entangle infrastructure concerns (like file I/O, CICS screen management, and DB2 access) with core business logic (like interest calculations, card limits, and merchant fee allocations). If you translate the code directly, you replicate that entanglement.

Semantic decomposition forces the AI to analyze the source code at a higher level of abstraction. The goal is to isolate the underlying business intent from the mechanical constraints of the legacy runtime platform.

image

When I feed code into an LLM engine for analysis, I change the instructions entirely:

  • The Transpiler Prompt (Wrong): "Translate this COBOL paragraph into a functional Java method."

  • The Decomposition Prompt (Right): "Identify the pure mathematical calculations and conditional rules in this COBOL paragraph. Strip out all file read/write operations, variable initializations, and display logic. Document the business rules in a declarative format."

By separating the core domain algorithms from the infrastructure layer, I can isolate a clean, pure processing engine. For example, a 2,000-line COBOL routine handling credit card interest accruals might boil down to a handful of pure, state-free logic loops once the mainframe-specific memory management and I/O logic are removed.

Prompt Workflows for Domain-Driven Design (DDD)

Once the core logic is extracted, the next step is restructuring it into code that aligns with modern Domain-Driven Design principles. Card solutions are highly transactional and stateful, making them ideal candidates for DDD patterns like Aggregates, Entities, and Value Objects.

To force an LLM to generate clean, decoupled interfaces rather than procedural scripts, I structure the prompt workflow into an iterative pipeline:

Step 1: Ubiquitous Language Discovery

First, I task the model with creating a data dictionary that bridges legacy variables to modern domain concepts. Mainframe code relies heavily on abbreviated, cryptic field names (e.g., TXT-AMT-AUTH-REQ). The LLM maps these to readable domain attributes (authorizedAmount, transactionCurrency) based on how they are manipulated in the business logic.

Step 2: Extracting the Aggregate Root

I instruct the LLM to identify the transactional boundaries. In a card processing context, the CardholderAccount or the MerchantTransaction acts as the Aggregate Root. The prompt explicitly restricts the LLM from creating deep, nested dependency classes, forcing it to model the core state changes as isolated, immutable operations.

Step 3: Generating Clean Interfaces

Finally, I instruct the LLM to generate code interfaces that follow the Hexagonal Architecture (Ports and Adapters) pattern. The business logic must remain pure and free from framework-specific dependencies (like Spring Boot or AWS SDKs).

Architectural Guardrail: I utilize highly constrained system prompts that enforce code design patterns. For instance: "Generate a Go interface for the card authorization domain logic. The domain layer must have zero imports outside of standard native types. All database mutations must be abstracted behind a repository interface port."

The resulting output is a beautifully decoupled service layer:

GO

// Clean Domain Service Layer - Free from Mainframe and Cloud Infrastructure
type AuthorizationService interface { ValidateTransaction(ctx context.Context, tx DomainTransaction) (*ApprovalStatus, error) } type AccountRepository interface { GetAccount(ctx context.Context, accountNumber string) (*CardholderAccount, error) UpdateBalance(ctx context.Context, account string, amount decimal.Decimal) error }

The Human-in-the-Loop Workflow: Framing Bounded Contexts

No matter how advanced LLMs become, letting an AI automatically generate an entire microservice architecture without guardrails invites chaos. The true power of generative AI in R&D emerges when it acts as an interactive drafting assistant for an enterprise architect.

My modernization workflow relies on an iterative, human-in-the-loop approach specifically designed to establish Bounded Contexts:

  1. AI-Driven Clustering: The multi-agent analyzer groups related legacy legacy programs based on data access patterns and common transactional boundaries. It proposes a list of potential microservices (e.g., Fee Engine Service, Clearing & Settlement Service, Fraud Scoring Proxy).

  2. Architectural Override: As the architect, I review this proposed boundary map. AI models lack context regarding organizational boundaries or long-term product roadmaps. I step in to adjust the scope—merging contexts where network latency would be prohibitive, or splitting them to match team structures (Conway’s Law).

  3. Refining the Anti-Corruption Layer (ACL): Because we cannot modernize everything at once, the new microservices must communicate with the remaining mainframe core. I use AI to draft the specifications for an Anti-Corruption Layer—a translation proxy that sits between our new, clean domain APIs and the legacy transaction monitors.

By using AI to rapidly draft, visualize, and iterate on these bounded contexts, I can cut down the macro-architectural design phase of a project from months to days.

Summary

Moving away from line-by-line code translation prevents the creation of unmaintainable JOBOL technical debt. By leaning heavily into semantic decomposition, engineering leaders can extract the pure, highly valuable business rules locked within legacy payment engines. This approach allows us to deploy clean, domain-driven microservices that are truly built for the cloud, while saving our engineering talent from maintaining a procedural nightmare disguised as modern code.

0 comments
4 views

Permalink