Dragging a Java 8 fossil from 2010 into the cloud. How far do you get without rebuilding it?

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

Arjan Franzen

27 May 2022

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

I have a piece of software lying around that I built around 2010: a helper for Asterisk, the open-source phone exchange, that fills the menus on a Cisco desk phone. Java 1.8, JAXB, Spring 3, the popular choices of the day. It still runs, but in a way nobody wants to maintain.

The question I asked myself is the one I hear from clients: how far do you get if you want to drag something like this into the present without rebuilding it? The size is that of a hobby project, the pattern is that of every old system I come across. I was expecting a long afternoon. It was one, and that surprised me.

What is this thing?

A Cisco IP phone has a small screen with a menu: Network, ProductInfo, Status, Reboot. The phone fetches those menus as small XML pages from my Java app, which talks to Asterisk on the other side. It does nothing else remarkable, which makes it a good guinea pig: no complicated logic, but every edge old software gets stuck on. An outdated Java version, a library that has since been taken out of Java, a framework three major versions back, and a way of deploying from 2010. That list is what legacy modernisation looks like in practice: the business logic is rarely the problem, the edges are.

What broke, and what went surprisingly well

JAXB turns XML into Java objects and back. In 2010 it was simply part of Java; by Java 11 it had been removed, so that was the first thing to fall over. It lives on as a separate library under the Eclipse flag, Jakarta XML Binding, and Jesper de Jong explains how to put it back: two dependencies, and the code stays shut.

Spring went from version 3 to 5 by raising the version number. No broken code, no hunt for a vanished class. Ten years of backward compatibility, and it was the part I had dreaded most.

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

App Engine said no, so Spring Boot it was

My first idea was Google App Engine: drop in a WAR and done. The local development server crashed straight away. Since Java 16 the internal doors of Java are locked and the App Engine server tries to prise one open. You can ask Java to unlock that door with a flag (a forum for Minecraft servers sets out exactly how, because they run into the same thing), or go back to Java 11. Both are a plaster on an old way of working.

Then I thought: why not go straight to Spring Boot? That gives you an app that runs itself, with a server built in, and something like that fits neatly into a container and therefore into Cloud Run, which scales to zero when nobody calls. Two steps in the pom.xml, and you do not even have to write a Dockerfile. Whether Cloud Run is enough or you need Kubernetes is covered in Cloud Run versus GKE; for a phone menu that opens a few times a day the answer is obvious.

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

The mess you only see once you start tidying

While moving house I came across something I had not done very neatly in 2010: two DispatcherServlets in the web.xml, one for /rest/* and one for /cisco/*, where an app should have one. It worked for ten years, so nobody ever looked at it, me included. That is the nature of legacy: decisions that seemed fine at the time and that you only find again when you take the roof off.

What this says about your old system

Of the four edges this app was stuck to, only one turned out to be real work: the way of deploying. The Java version was an afternoon, the vanished library two lines, and the framework came along by itself. I see the same thing at companies. The system is rarely as rotten as it feels; what is rotten is the path around it.

Which is why I rarely recommend a rebuild. Move the edges first, one at a time, and leave the business logic alone until it asks to be replaced; for large systems that is the strangler pattern. Stuck on an upgrade of Java, Spring or something else from that era? That is the work we do in legacy modernisation, and my prediction is that your system gets further than you think too.

no image placeholder

Optimize with ZEN's Expertise

How we can help

Cloud & platform

Landing zones on AWS and Google Cloud, CI/CD and observability. We set it up, and we keep it running.

See cloud & platform →