The Java network programming world has come a long way since Undertow was
first started. Netty has emerged as the de-facto standard for network
programming in Java, and the Undertow team has decided that the benefits of
utilising Netty outweigh any benefits in keeping our XNIO based transport
Undertow 3.0 will keep Undertow’s programming model, however the underlying
transport will be changed from XNIO to Netty. We will also use the Netty
HTTP/1, HTTP/2 and Websocket implementations. We believe this change will
have a number of advantages:
It will allow other Netty based services (e.g GRPC) to share the same
It allows sharing of threads between Undertow and other Netty based
services, resulting in services using less resources
The underlying transport implementation are the most complex part of
Undertow, delegating this to Netty will significantly reduce the work
needed to maintain Undertow
As part of this Flavia Rainone will be taking over as project lead from
Stuart Douglas so he can focus on the recently announced Quarkus project,
however Stuart will continue to be heavily involved in Undertow for the
Flavia Rainone has been involved in JBoss community since 2002 and has an
extensive background on Remoting and Xnio. In the past years, she acted as
EJB component lead for WildFly, besides contributing to several projects
in WildFly, such as IronJacamar, JBoss MSC and XNIO, and also Byteman. All
this makes her a good fit for taking over Undertow leadership.
What does this mean for me?
What this means for you will depend on which parts of Undertow you are
If you are using the Servlet API then you will likely not notice any
change. You will need some different dependencies (Netty instead of XNIO),
however the rest of the experience should be mostly identical
If you are using the low level Undertow HttpHandler and
HttpServerExchange and you want to use Undertow 3.0 then you will need to
migrate your application. For the most part this migration should be
straightforward, as most concepts from the old API directly map to the new
The existing Undertow 2.x branch will continue to be maintained for the
foreseeable future. It will receive bug and security fixes, and some
features, however it is unlikely to receive any more low level transport
oriented features (e.g. HTTP/3 support). For now it is a perfectly valid
choice to stay on Undertow 2 while the new Netty based implementation
A 3.0 final version should be released in the next few months, however in
the short term the 3.x branch will not provide the same level of API
compatibility that Undertow has traditionally provided. As the Netty
implementation is new this will allow us to potentially fix any issues we
find with our approach without being locked in to supporting an API that is
This is a great time to try out the new API and report and problems or
suggestions. Note that this is explicitly referring to the core
HttpServerExchange based API, no major plans are expected to the Servlet
API (i.e. ServletExtension and DeploymentInfo).
After a short 3.x cycle we are planning on releasing a 4.x that will
provide API stability, in the same way that Undertow 1.x and 2.x have.
How can I contribute
You can contribute to Undertow in the same way it has always been done.
We have an email list open for discussion here: undertow-dev(a)lists.jboss.org
Jira issues can be accessed here:
And source code for 3.x is here:
Also, with the move from HipChat to Zulip in Wildfly team, you can now
access Undertow stream via Zulip at https://wildfly.zulipchat.com/
I was working on a web server implemented with undertow and came across
a weird inconsistency. When setting the response content length of an
exchange and then writing to its output stream, normally the output
self-closes as soon as the proper content length is hit. However, it
turns out that this does not happen when content length is zero. This
leads to the response remaining open if you've previously dispatch()ed it.
The code in question is here:
- the relevant bit goes as follows:
... later ...
(I'm aware that I should avoid no-arg dispatch, and that I should be
closing the output stream - this was a rushed side project)
I've tracked down the issue to this class:
Normally, updateWritten(long) checks whether the content length has been
reached and if so, closes the stream and writes the response. However,
when passing an empty array to write(byte, int, int), we run into a
length check and updateWritten is never executed, and thus the stream is
Is this a bug? I know the issue came from me using undertow improperly,
but it certainly is inconsistent. To me it seems like the idea here is
to close the stream when the response is done, which does not happen
when writing a 0-length array. However it could also be argued that
outputstream.write(new byte) should never do anything.
If this is a bug, I'll happily make an issue and a PR for it if that's
better for you - it doesn't look like it's that much work.
Hello Undertow lovers,
I have two instances of undertow, one acting as a reverse proxy via
LoadBalancingProxyClient to the other that configured with the AJP
Everything works well but I just noticed an issue with proxying WebSocket
I Googled around and it seems that APJ and WebSockets don't work together.
I was wondering if Undertow has some soluting for proxying WebSocket
connections over APJ or if I must fallback to http listener.
Any help would be much appreciated.
Thanks in advance,