Een Java 8-fossiel uit 2010 naar de cloud slepen. Hoe ver kom je zonder alles opnieuw te bouwen?

Crowds of fun-seekers exploring a city on foot, "

Arjan Franzen

27 mei 2022

Illustratie: een gefossiliseerde bureautelefoon in een steenplaat, een archeoloog veegt het stof eraf en een kabel loopt van het fossiel naar een wolk

Ik heb een stukje software liggen dat ik rond 2010 heb gebouwd: een hulpje voor Asterisk, de open-source telefooncentrale, dat de menu's op een Cisco-bureautelefoon vult. Java 1.8, JAXB, Spring 3, de populaire technieken van toen. Het draait nog, maar op een manier die niemand meer wil onderhouden.

De vraag die ik mezelf stelde hoor ik ook bij klanten: hoe ver kom je als je zoiets naar het heden wilt slepen, zonder het opnieuw te bouwen? De omvang is die van een hobbyproject, het patroon dat van elk oud systeem dat ik tegenkom. Ik was op een lange middag uit. Het werd er één, en dat verbaasde me.

Wat is dit voor ding?

Een Cisco IP-telefoon heeft een klein scherm met een menu: Network, ProductInfo, Status, Reboot. Die menu's haalt de telefoon als kleine XML-pagina's op bij mijn Java-app, die aan de andere kant met Asterisk praat. Verder doet hij niets bijzonders, en daarom is hij een goed proefkonijn: geen ingewikkelde logica, wel alle randen waar oude software aan vast zit. Een verouderde Java-versie, een bibliotheek die uit Java is gehaald, een framework van drie grote versies terug, en een manier van deployen uit 2010. Dat rijtje is wat legacy moderniseren in de praktijk is: de bedrijfslogica is zelden het probleem, de randen zijn het probleem.

Wat brak, en wat verrassend goed ging

JAXB zet XML om naar Java-objecten en terug. In 2010 zat het gewoon in Java, in Java 11 is het eruit gehaald, dus dat was het eerste dat omviel. Het leeft verder als losse bibliotheek onder de vlag van Eclipse, Jakarta XML Binding, en Jesper de Jong legt uit hoe je het terugzet: twee afhankelijkheden erbij, de code hoeft niet open.

Spring ging van versie 3 naar 5 door alleen het versienummer te verhogen. Geen gebroken code, geen zoektocht naar een verdwenen klasse. Tien jaar achterwaartse compatibiliteit, en uitgerekend het deel waar ik het meest tegenop zag.

1 <!-- JAXB API -->
2<dependency>
3    <groupId>jakarta.xml.bind</groupId>
4    <artifactId>jakarta.xml.bind-api</artifactId>
5</dependency>
6<!-- en de implementatie -->
7<dependency>
8    <groupId>org.glassfish.jaxb</groupId>
9    <artifactId>jaxb-runtime</artifactId>
10</dependency>

App Engine zei nee, dus werd het Spring Boot

Mijn eerste idee was Google App Engine: WAR neerzetten en klaar. De lokale ontwikkelserver crashte meteen. Sinds Java 16 zitten de interne deuren van Java op slot en de App Engine-server probeert er een open te peuteren. Je kunt Java met een vlag vragen die deur toch open te zetten (op een forum voor Minecraft-servers staat precies hoe, want daar lopen ze tegen hetzelfde aan), of terug naar Java 11. Allebei een pleister op een oude manier van werken.

Toen dacht ik: waarom niet meteen naar Spring Boot? Dat levert een app die zichzelf draait, met een ingebouwde server, en zoiets past precies in een container en dus in Cloud Run, dat naar nul schaalt als niemand belt. Twee stappen in de pom.xml, en een Dockerfile hoef je niet eens te schrijven. Of Cloud Run genoeg is of dat je Kubernetes nodig hebt staat in Cloud Run versus GKE; voor een telefoonmenu dat een paar keer per dag opengaat is het antwoord duidelijk.

1 gcloud run deploy phone-menu --source . --region europe-west4

De rommel die je pas ziet als je gaat opruimen

Tijdens het verhuizen kwam ik iets tegen wat ik in 2010 niet zo netjes had gedaan: twee DispatcherServlets in de web.xml, een voor /rest/* en een voor /cisco/*, terwijl er maar één in een app hoort. Het werkte tien jaar, dus niemand heeft er ooit naar gekeken, ik ook niet. Dat is de aard van legacy: beslissingen die toen prima leken en die je pas terugvindt als je het dak eraf haalt.

Wat dit zegt over jouw oude systeem

Van de vier randen waar deze app aan vastzat, bleek er maar één echt werk: de manier van deployen. De Java-versie was een middag, de verdwenen bibliotheek twee regels, en het framework ging vanzelf mee. Bij bedrijven zie ik hetzelfde. Het systeem is zelden zo rot als het voelt; wat rot is, is het pad eromheen.

Daarom raad ik zelden een herbouw aan. Verhuis eerst de randen, één tegelijk, en laat de bedrijfslogica staan tot hij zelf om vervanging vraagt; voor grote systemen heet dat het strangler pattern. Loop je vast op een upgrade van Java, Spring of iets anders uit dat tijdperk? Dat is het werk dat wij bij legacy moderniseren doen, en mijn voorspelling is dat jouw systeem ook verder komt dan je denkt.

no image placeholder

Softwareontwikkeling ontmoeilijken

Hier helpen we mee

Cloud & platform

Landing zones op AWS en Google Cloud, CI/CD en observability. We richten het in, en we houden het draaiend.

Bekijk cloud & platform →