The Jetty 12 Adapter for Clojure Ring, and A Decade of A Custom Ring Adapter

The Jetty 12 Adapter for Clojure Ring

The 12.0 release of Jetty saw its most important architectural change: the split of its Jetty-Core API and enterprise Java APIs. The Jetty-Core API is fully functional for Java server and client development, and is the first version of Jetty that being Servlet-free.

My Clojure library ring-jetty9-adapter has been tracking Jetty's development since early release of 9.0 (also named after that version). During the last few weeks I worked with @jasonjckn to port this adapter to Jetty 12, making its name even more confusing :). Thanks to previous changes, the core library of Ring no longer depends on Servlet API. So in this upgrade, we removed Servlet API completely in ring-jetty9-adapter. The handler and request/response implementation has been rewritten to match those from Jetty-Core, while keeping it compatible with Ring spec.

The new version has been released to clojars as 0.30.0. To upgrade to this version, note that:

  • Of course, access to Servlet API in your Clojure code is now invalid
  • Java 17 is now required
  • :async-timeout option is removed, let me know if your application relies on it

We saw at least 10% throughput improvement thanks to less layer of abstraction. As early adopters of Jetty-Core API, I'm giving shout-out Jetty maintainers @joakime, @sbordet and @lorban for their help during the upgrade.

A Decade of A Custom Ring Adapter

While working on this upgrade, I noticed that the library was started exact 10 years ago in 2013 when I was a full-time Clojure developer at AVOS. It was born because at that time, the official Jetty adapter stuck on version 7. The WebSocket API in Jetty 9 was what we needed for our Clojure/Ring based application.

But I didn't stop there. During the last 10 years, with help from many contributors, I managed to keep adding new features to this library, making it a feature-rich alternative to the official one:

  • 2013/4, the initial release based on Jetty 9.0.3, with WebSocket API
  • 2015/7, HTTP/2 connector
  • 2017/5, Async Ring handler
  • 2018/9, TLS 1.3 as default SSL protocol
  • 2020/7, JDK 11 and JDK 8u252 upgrade, removal of Conscrypt
  • 2020/12, Jetty 10 upgrade
  • 2021/10, WebSocket protocol upgrade, making it possible to return websocket callbacks from a ring handler
  • 2022/2, HTTP/3 connector
  • 2022/10, Jetty 11 upgrade
  • 2023/9, Jetty 12 upgrade, virtual threads and removal of servlet

A total downloads of 237,550 and 83 releases is how it benefits the community.

As I'm no longer using Clojure at my work, this library has been my last few direct connections to the programming language I always enjoy a lot. Using it in my side projects is still a lot of fun. I'm looking forward to run this project in next decade.