The Joy of Building Something That Doesn’t Matter
Or, how a forgotten Java app gave me a peaceful morning I didn’t know I needed.
Back in the early 2010s, I built a little desktop app called sTodo — a simple Swing-based to-do list. Nothing fancy. It had a lightweight plugin system powered by the old Rhino JavaScript engine, and I remember enjoying how it gave users the ability to customize features with scriptable behavior.
The core idea behind sTodo was to use JavaScript to let users customize a Java application — effectively building a bridge between the two worlds. It wasn’t just about flexibility; it was about making the app feel alive and malleable, even if only to someone curious enough to peek behind the scenes. That connection — between a static Java UI and the dynamic nature of JavaScript — was what made it exciting to me back then.
More than a decade later, I stumbled across it again while digging through some old blog posts. I remembered the joy of building it and decided — why not try to bring it back to life?
🔥 The Attempt
By 2023, Rhino was long gone from most setups, so I turned to GraalVM, hoping to modernize the engine behind my plugin system. I wanted to support the same Java interop features, like dynamically implementing interfaces from JavaScript — something that used to be easy with JavaAdapter
.
That was when I first hit the wall.
Java.newProxy
was missing.
JavaAdapter
was gone.
Even with --polyglot --jvm
, the JavaScript engine refused to let me in.
So I turned to ChatGPT.
It offered helpful suggestions — building a Context
with allowAllAccess(true)
, HostAccess.ALL
, and HostClassLookup
. It made sense. I refactored the plugin loader, replaced ScriptEngineManager
with Graal’s newer APIs, and double-checked every configuration line.
But Java.newProxy
still didn’t work.
I fought with environment variables, switched between SDKMAN and asdf, rebuilt the project, reset IntelliJ’s project structure, even tried multiple versions of GraalVM. Still stuck.
🌙 The 4AM Realization
At 4 in the morning, in the quiet cold of a Melbourne autumn, I woke suddenly. Not from noise — from a thought.
“I think I forgot to call execute on the plugin script when it’s loaded…”
The NullPointerException
I’d been chasing? It wasn’t about GraalVM’s context isolation at all — it was just a script that never ran. A regular bug, hidden behind all the tooling noise.
I got up, back aching, and messaged my team to take a day off. I couldn’t let this go. I made a coffee, sat down, and began again.
😩 ChatGPT, Still Suggesting Java.newProxy
Despite fixing the execute()
issue, I was still stuck with the JavaScript integration. ChatGPT kept nudging me toward Java.newProxy
, but by then I had serious doubts.
The suggestion sounded nice — but I’d already tried it. Many times.
Still, I was willing to try one more thing.
🫥 Claude’s Suggestion
With a bit of hesitation, I asked Claude — another AI — for help. The response looked almost identical to what I had before. Nothing new, really.
But for some reason, I pasted it in anyway.
It didn’t use Java.newProxy
.
It just used good old-fashioned:
menuItemHelp.addActionListener(new ActionListener() {
actionPerformed: function(event) {
var hDialog = new HelpDialog(null, "This is Help");
hDialog.setVisible(true);
}
});
And then... it compiled. Everything worked.
🧸 The Quiet Win
No fireworks. Just a small, satisfying click.
I shared the story with a friend
— one of the few people I knew would understand my quiet joy.The plugin system was running. The menus were building. Tooltips showed up. SQLite worked. I’d even modernized the HTML in my tooltip renderer.
It wasn’t groundbreaking. Just an old app from a decade ago, revived on a whim. It won’t change anyone’s life — probably not even mine. But I enjoyed the process.
There was something oddly comforting about it. No pressure. No deadlines. Just me, tinkering with a project that probably only I would use.
It reminded me of why I started coding in the first place — for that calm, focused feeling of building something from nothing. Not for business value or metrics or productivity hacks. Just to create.
After all the misdirection and late-night frustration, I found myself in a surprisingly peaceful place. Not because I solved a hard problem. But because I made something again.
Surely, if you want to see the code: https://github.com/abruzzi/stodo. Don’t expect too much — it’s a 15-year-old program already.