<< Posts

Rewriting my web server in Java

It was a relatively quick turnaround, but I’ve rewritten the hosting layer of this website yet again. A rewrite was not deserved, but there were exciting reasons why I wanted to give it a try and a couple of reasons why I lost interest in the current project.

Annoyances in the chimer web server and website I’d written on top of it were the main drag on motivation to continue development. On the web server side, I eventually came to dislike the event driven callback nature of libuv. The other alternative library I’d considered was Boost’s ASIO, but it’s always been an inscrutably complicated system that I’ve never been able to make headway with. I ended up missing the high level and (relatively) uncomplicated nature of C#’s async/await which is something very difficult to re-create or reason about in a native language. I also eventually disliked the templating system I’d created for displaying each web page. It was modeled after a builder pattern where each html element could be appended together, had children, etc. While this seemed like a good idea at the time, it was much harder to use and maintain than a textual based templating system like Jinja in Python.

None of these things were an unreasonable amount of work to fix considering the time I’ve already invested in chimer. However, it was just enough to make a complete rewrite in another language enticing. I spend all day at work writing and reviewing C++ and C# code so doing something different enough to make working on it interesting each day an important thing. Go was heavily considered, but if the goal is to write an HTTP server from scratch, Go already has one built into the standard library… which kills my own motivation a bit. Java seemed like an ideal thing to switch to. It’s memory-safe and, while it doesn’t have async/await, newer versions of the JDK introduced virtual threads which seem (to my, admittedly, naïve understanding) a lot closer to the idea of Go’s goroutine. Virtual threads were the feature that convinced me of Java. They seem like a breath of fresh air compared to event-based and async/await paradigms and allow for the simple mental model of a “thread” per request in a server application.

So, after a few weeks of work, I have full feature parity between chimer and this new web server and website. The HTTP parser is better tested and implements more of the HTTP/1.1 spec than chimer ever did. I’ve also migrated the actual nathanieljwright.com web pages to using the Freemarker templating system on top of the homegrown HTTP server which seems a lot more maintainable in the long term.