
De COBOL-migratie die perfect compileerde — en toch het grootboek corrumpeerde
De code was perfect. Dat was precies het probleem.
Een programma voor overboekingen was van COBOL naar Java vertaald. Het compileerde. De unittests slaagden. Het passeerde elke controle die we hadden gebouwd om fouten op te vangen. Toen, tijdens de gebruikersacceptatietest, deed de allereerste transactie de consistentiecontrole van de database struikelen en stortte het hele geheel in.
De autopsie duurde langer dan zou moeten, want niets in de Java zag er verkeerd uit. De boosdoener was een variabele genaamd TRN-LIMIT. De vertaaltool had die gelezen als een gewoon getal en er een standaard integertype aan toegekend. Maar TRN-LIMIT was nooit gedefinieerd waar de tool keek. Het was gedeclareerd in een copybook — een gedeeld headerbestand — dat duizenden regels eerder in de uitvoeringsketen werd binnengehaald, en dat copybook bevatte een REDEFINES-clausule: een COBOL-constructie waarmee dezelfde geheugenplek als twee volkomen verschillende datatypes kan worden gelezen, afhankelijk van een vlag die ergens anders wordt gezet. Op de mainframe bevatte dat adres een packed decimal. De nieuwe Java-code schreef beschadigde binaire data naar de databasekolom, en de referentiële integriteit van het grootboek bezweek.
De code was syntactisch foutloos. Het falen was contextueel. De tool had een afhankelijkheid gemist die buiten zijn gezichtsveld lag — en bij de modernisering van legacy COBOL is dat vrijwel altijd hoe het geld verdwijnt.
Moderniseringsprojecten sneuvelen doorgaans niet op de code die je kunt zien. Ze sneuvelen op de code die de tool niet kon zien.
Dit is het verhaal van waarom ik stopte met geloven dat betere vertaling het antwoord was, en wat we bij Veriprajna in plaats daarvan bouwden.
Waarom demonstreert "plak COBOL, krijg Java" altijd zo goed?
Als je de afgelopen twee jaar in een vergadering over mainframemodernisering hebt gezeten, heb je de pitch gehoord: plak je COBOL, krijg Java terug. Het is verleidelijk omdat de demo altijd werkt. Iemand plakt er een net programma van 200 regels in, het model retourneert schone, idiomatische Java, en iedereen in de kamer haalt opgelucht adem. Eindelijk.
Ik geloofde het ook, een tijdlang. Toen mijn team er voor het eerst aan begon, deden we het voor de hand liggende — we probeerden de vertaling beter te maken. We voedden modellen met meer context, stemden ze af op de eigenaardigheden van COBOL, benchmarkten de outputkwaliteit. Er bestaat zelfs een fijngetuned open model genaamd XMainframe, speciaal hiervoor gebouwd, dat op COBOL-taken ongeveer 30% hoger scoort dan generieke codemodellen. De vertalingen werden schoner. De Java werd leesbaarder.
En toch brak het in de UAT. Keer op keer, precies op het soort verborgen afhankelijkheid dat dat overboekingsprogramma had gekelderd. Dat was de maand waarin ik besefte dat we het verkeerde aan het oppoetsen waren. De kwaliteit van de vertaling was nooit het knelpunt. De code die compileert is het makkelijke deel. Het moeilijke deel is de code die de tool niet kan zien.
De cijfers hierover zijn keihard en consistent: 70 tot 80% van de mainframemoderniseringsprojecten haalt zijn doelstellingen niet. Niet 70% loopt uit — 70% mislukt. De gebruikelijke diagnose wijst naar onderschatte tests of rommelige datamigratie, en die zijn reëel. Maar onder vrijwel al deze projecten ligt dezelfde grondoorzaak die ik zojuist live had zien gebeuren: de tools behandelen een codebase als tekst die geconverteerd moet worden, terwijl het eigenlijk een topologie is die begrepen moet worden.
Wat "plak COBOL, krijg Java" niet kan zien

Zodra je begint te letten op contextuele blindheid, zie je die overal. Drie patronen deden ons het vaakst de das om, en geen ervan is zichtbaar in het bronbestand waar een vertaler naar staart.
Begin met het copybook-probleem dat ik al beschreef. Eén enkel COBOL-programma kan naar meer dan veertig copybooks verwijzen, en die copybooks bevatten andere copybooks, zodat de werkelijke definitie van een variabele meerdere niveaus diep in de inclusieketen kan liggen. Een tekstgebaseerde tool leest de instructie die voor hem staat en leidt er een type uit af. Het heeft geen manier om te weten dat die gevolgtrekking bij een packed-decimalveld stilzwijgend verkeerd is.
Dan is er het rekenwerk. COBOL's COMP-3 packed decimal heeft geen native equivalent in Java. Grijp naar een double en je hebt zojuist floating-point-afronding geïntroduceerd in een systeem dat geld verplaatst. Zelfs BigDecimal, het juiste gereedschap, komt standaard niet overeen met COBOL — je moet de afrondingsmodus expliciet vastzetten op HALF_EVEN om COBOL's ROUNDED-clausule na te bootsen. Doe je het verkeerd, dan zit je er een cent per transactie naast. Die cent stapelt zich op over miljoenen transacties tot, weken later, een reconciliatierapport een verschil signaleert dat niemand kan verklaren.
Het patroon dat bijna iedereen vergeet is het patroon dat de productie daadwerkelijk platlegt: je COBOL draait niet uit zichzelf. Een scheduler — CA-7 of TWS — orkestreert ergens tussen de tweeduizend en vijfduizend batchjobs, met afhankelijkheidsketens die erdoorheen zijn geregen. Job A schrijft om 1 uur 's nachts een dataset die Job B om 2 uur 's nachts leest. Je kunt elke regel COBOL foutloos migreren en toch de bank om middernacht platleggen, omdat niemand het jobnetwerk in kaart had gebracht. De productiegraaf stond nooit in de broncode. Die stond in de JCL.
De job die de productie om 2 uur 's nachts platlegt, is nooit de job waar je naar keek.
Dit is wat ik met topologie bedoel. Het artefact dat je bedrijf daadwerkelijk laat draaien is een web van relaties — programma's, copybooks, datasets, geplande jobs, DB2-tabellen, CICS-transacties — en de COBOL-broncode is er slechts één streng van.
Waarom ik de vertaler niet langer vertrouwde en de kaart begon te tekenen

Het kantelpunt voor ons was de beslissing dat de kaart het product is.
Voordat we ook maar één regel vertalen, bouwen we een kennisgraaf van de volledige codebase — elk programma, elke copybook-verbinding, elke JCL-afhankelijkheid, elke dataset-overdracht, elk DB2-aanknopingspunt — en lossen we de transitieve relaties op die de bronbestanden verbergen. Wanneer je kunt zien dat één programma veertig-plus copybook-verbindingen heeft en dat één ervan twee modules verderop een REDEFINES draagt, gebeurt de TRN-LIMIT-ramp gewoon niet, want je wist dat het veld packed decimal was voordat je één teken Java had getypt.
Ik wil precies zijn over waarom dit anders is dan wat de rest van het veld verkoopt, want het veld is druk en het meeste ervan is oprecht goed in het deel dat het oplost.
IBM's watsonx Code Assistant for Z is de serieuste gevestigde partij — een agentisch systeem, met orkestratie-, architectuur- en code-agents, dat COBOL-naar-Java aankan en zelfs PL/I en IMS, en dat CPU-verbruik tot diep in de copybooks analyseert. Het is ook een verplichting van $2 miljoen-plus die op z/OS draait en leunt op IBM's ADDI-tooling, wat je stilletjes vastketent aan de mainframe tijdens de migratie die je er juist van moest bevrijden. Het doet geen gedragsequivalentietests, en het brengt je JCL-jobnetwerk niet in kaart.
Dan is er het moment dat de hele markt hervormde. In februari 2026 publiceerde Anthropic een COBOL-moderniseringsdraaiboek voor Claude Code; het aandeel van IBM daalde op de dag van de aankondiging met 13,2%, en in maart volgde een partnernetwerk van $100 miljoen. Claude Code is uitstekend in ontdekking, documentatie en het lezen van onbekende code — oprecht nuttig in de vroege fasen. Maar het is een generiek gereedschap. Het heeft geen ingebouwde kennisgraaf om transitieve afhankelijkheden op te lossen, en het beweert niet JCL-planning, gedragsequivalentie of de audittrails op te lossen die een gereguleerde bank moet produceren.
Microsofts Azure-migratiefabriek richt zich op Java Quarkus en ketent je doelplatform vast aan Azure. De grote systeemintegrators — DXC met zijn gepatenteerde conversie-engine, TCS met MasterCraft, Infosys met Cobalt, Accenture — draaien opdrachten van $500K tot $5M-plus en implementeren leverancierstools in plaats van intelligentie op te bouwen over jouw systeem; Accenture leidde de kernmigratie van de Commonwealth Bank of Australia die ongeveer $749,9 miljoen kostte en vijf jaar duurde. En Micro Focus' Visual COBOL, vaak aangeprezen als startpunt, is helemaal geen modernisering — het is rehosting. Je COBOL blijft COBOL, alleen op een nieuwe runtime. De technische schuld en het personeelsprobleem staan precies waar je ze achterliet.
Elk van deze doet iets reëels. Wat geen ervan doet, is de volledige afhankelijkheidstopologie bouwen — JCL, CICS, DB2, copybooks en al — eerst, onafhankelijk van welk doelplatform dan ook, en die kaart behandelen als het fundament waarop al het andere rust.
De meeste leveranciers verkopen je een betere vertaler. De vertaling was nooit het deel dat faalde.
De klok die niemand kan stoppen
Hier komt het deel dat dit van een engineeringprobleem in een noodgeval verandert.
De mensen die deze systemen begrijpen, vertrekken. De gemiddelde COBOL-ontwikkelaar in de VS is rond de 55. Ruwweg 10% van dat personeelsbestand gaat elk jaar met pensioen, en 85% van de universiteiten schrapte COBOL al in de jaren negentig uit het curriculum, dus vrijwel niemand vervangt hen. Zestig procent van de organisaties zegt nu dat het vinden van bekwame COBOL-ontwikkelaars hun grootste moderniseringsuitdaging is — en 58% van de ontwikkelaars die deze stacks nog kennen, zegt te overwegen ermee te stoppen vanwege die stacks.
Ik heb gestaan bij de versie hiervan die me achtervolgt: het afscheidsfeestje voor de enige persoon die het batchvenster daadwerkelijk begreep. Iedereen glimlacht, er is taart, en ergens achter in mijn hoofd zegt een stem: die kennis is zojuist de deur uit gelopen en het staat nergens opgeschreven. Een kennisgraaf is, onder andere, een manier om vast te leggen wat er in het hoofd van die persoon zit vóór het feestje — om de afhankelijkheidskaart de mensen te laten overleven die hem uit hun hoofd kenden.
En de inzet is niet klein of abstract. Zo'n 220 miljard regels COBOL draaien nog altijd actief in productie. Het verwerkt 95% van de pinautomaattransacties en verrekent ruwweg $3 biljoen per dag. Drieënveertig procent van de banksystemen is erop gebouwd. De technische schuld in de VS wordt geschat op $1,52 biljoen, en de gemiddelde onderneming verbrandt zo'n $370 miljoen per jaar aan legacy-inefficiëntie, waarbij financiële dienstverleners 70 tot 75% van hun IT-budget alleen al besteden aan het in leven houden van de oude systemen. De teams die de migratie goed doen, melden rendementen van 114 tot 225% en ongeveer $25 miljoen per jaar aan besparingen — maar die winst bestaat alleen aan de andere kant van een migratie die niet mislukte. Dit is die zeldzame modernisering waarbij niets doen de dure optie is.
Lossen de nieuwe AI-tools dit niet gewoon op?
Dit is de vraag die ik het vaakst krijg, en die is terecht, zeker nadat de aankondiging van Anthropic het deed lijken alsof het probleem zojuist opgelost was verklaard.
Mijn eerlijke antwoord: de nieuwe tools maakten de ontdekkingsfase dramatisch sneller, en dat is echte vooruitgang — ik gebruik ze. Maar dat agentic AI goed wordt in het lezen van COBOL verandert niets aan datgene wat projecten daadwerkelijk om zeep helpt. Gartner verwacht dat 40% van de bedrijfsapplicaties tegen 2026 taakspecifieke AI-agents zal bevatten; meer agents die sneller code vertalen helpt niet als ze allemaal blind zijn voor dezelfde JCL-afhankelijkheid. Snelheid op het verkeerde probleem is gewoon een snellere manier om de UAT te bereiken en daar te falen.
De andere vraag die ik krijg gaat over regelgeving, en dat is de vraag die middenklassebanken onderschatten. De Digital Operational Resilience Act van de EU — DORA — trad in januari 2025 in werking en eist operationele veerkracht en threat-led penetratietesten waarvoor legacy-systemen simpelweg nooit ontworpen waren. Amerikaanse toezichthouders bij de FFIEC en OCC behandelen verouderde infrastructuur als een actuele compliancekloof, en systemen ouder dan tien jaar dragen ruwweg drie keer zoveel kans op een datalek. Een migratie die geen audittrail kan produceren die bewijst dat het nieuwe systeem zich identiek gedraagt aan het oude, is geen modernisering — het is een nieuwe aansprakelijkheid met betere syntaxis.
Daarom doet gedragsequivalentietesten er net zoveel toe als de kaart. De techniek is eenvoudig te beschrijven en moeilijk goed uit te voeren: leg echte in- en uitvoer vast uit het legacy-systeem — een golden dataset — en speel die af tegen het nieuwe totdat het gedrag overeenkomt, randgeval voor randgeval. Die randgevallen, opgebouwd over decennia, coderen vaak regelgevende logica die nergens anders bestaat — niet in een specificatie, niet in iemands hoofd, alleen in de draaiende code. Ik heb dit een verzekeraar harder zien bijten dan een bank: de tariefregel die alleen afgaat bij een polisaanhangsel uit 1998, de berekening van de schadereserve waarvan niemand die nu leeft de afronding kan verklaren, maar waar elke audit van afhangt. Verlies ze stilzwijgend en je komt erachter welke ertoe deden op de dag dat een toezichthouder ernaar vraagt.
Welke steen trek je er als eerste uit?
Zodra je de kaart hebt, vertelt die je iets wat geen enkele vertaler kan: waar het veilig is om te beginnen.
De dominante strategie nu — met goede reden — is de wurgvijg: in plaats van een big-bang-herschrijving haal je één capaciteit tegelijk eruit, laat je oud en nieuw naast elkaar draaien, en houd je het legacy-systeem als levende terugvaloptie totdat het nieuwe stuk vertrouwen heeft verdiend. Maar elke leverancier die de wurgvijg aanbeveelt, laat de moeilijkste vraag weg — welke module wurg je als eerste? Kies een sterk gekoppelde module en je hebt het big-bang-risico opnieuw gecreëerd, met extra stappen.
De kennisgraaf beantwoordt die vraag rechtstreeks. Hij brengt de modules met de laagste koppeling naar boven — die met de minste inkomende afhankelijkheden — zodat je een echt stuk van het systeem kunt lostrekken, de aanpak kunt bewijzen en organisatorisch vertrouwen kunt opbouwen voordat je aan de gevaarlijke kern komt. De kaart is niet alleen verzekering tegen de TRN-LIMIT-fout. Het is het volgordeplan.
We bouwden dit allemaal — de afhankelijkheidskennisgraaf, de wurgvijg-volgorde, het gedragsequivalentie-testkader, doelbewust onafhankelijk van welk doelplatform dan ook — in Veriprajna's praktijk voor de modernisering van legacy COBOL, precies gericht op de middenklassebanken en verzekeraars die de gevestigde partijen met een ondergrens van $2M en de SI's met zevencijferige tarieven te klein vinden om zich mee bezig te houden.
Waar ik eerlijk over ben
Ik doe niet alsof de technologie alles oplost, want de duurste mislukkingen die ik heb gezien, waren helemaal niet technisch.
Geen enkele tool — de onze inbegrepen — lost organisatorische steun op, ruimt jaren van slechte data op, of wint het politieke gevecht om tweehonderd ontwikkelaars te overtuigen hun werkwijze te veranderen. De markt zal naar verwachting groeien van ongeveer $9 miljard in 2026 naar het dubbele tegen het einde van het decennium, juist omdat zoveel van de uitgaven naar de menselijke en organisatorische laag gaat, niet naar de compiler. En geen enkele parser ter wereld, open source of commercieel, dekt perfect elke constructie in IBM Enterprise COBOL — de pre-1985 ALTER-instructies, de diepste REDEFINES. Wie je iets anders vertelt, verkoopt je de kloof. De technologie is noodzakelijk. Ze is nooit voldoende geweest.
Maar het deel dat de technologie wél kan bezitten, moet ze volledig bezitten. De reden dat migraties miljoenen verbranden en niets opleveren, is zelden dat iemand slechte Java heeft geschreven. Het is dat ze een systeem vertaalden dat ze nooit echt in kaart hadden gebracht — strengen van een web converterend terwijl het web zelf onzichtbaar bleef tot de nacht waarin het scheurde.
Teken eerst de kaart. Een systeem dat de mensen die het schreven heeft overleefd, vergeeft geen gemiste afhankelijkheid, en er bestaat geen versie van dit werk die veilig is voordat je kunt zien wat met wat verbonden is. We leerden dat van een grootboek dat om zeep werd geholpen door één enkel packed-decimalveld waarvan niemand wist dat het er was. Vind die velden voordat zij jou vinden.


