microBean™ Jersey Netty Integration
Jersey can be run as a simple handler of sorts in a Netty pipeline. The Netty event loop remains unblocked, there is no locking, reads and writes involve no copying of byte arrays, output is streamed where appropriate and it is intended that there be as few object allocations as possible.
This project uses semantic versioning. It is still in an alpha state.
Add a dependency on this project in your Netty-based Maven project:
<dependency> <groupId>org.microbean</groupId> <artifactId>microbean-jersey-netty</artifactId> <version>0.21.0</version> </dependency>
serverBootstrap.childHandler(new JerseyChannelInitializer(baseUri, // e.g. URI.create("/") sslContext, // an SslContext, or null if you don't want TLS support true, // yes, HTTP/2 support please 20971520L, // 20MB maximum incoming payload (arbitrary) new DefaultEventExecutorGroup(8), // a DefaultEventExecutorGroup with 8 threads (arbitrary) to run your application true, // yes, use Jersey's native dependency injection facilities new ApplicationHandler(yourJaxRsApplication), // the ApplicationHandler wrapping your application 8192, // write in 8K chunks (arbitrary) Unpooled::new /* how to create those chunks */));
Background and Motivation
While Jersey itself contains a Netty integration
it is annotated with
and the author additionally writes that his "implementation cannot be
more experimental". In addition, there are several issues with the
Jersey-supplied Netty integration project. The most problematic seems
to be issue
3500. This issue
and others stem from the fact that the Jersey-supplied Netty
integration project sets up its own internal queues for streaming,
which overflow. Additionally, new
are allocated throughout. It is also not entirely clear if HTTP/2 is
By contrast, microBean™ Jersey Netty Integration approaches the problem of running a Jakarta RESTful Web Services application under Netty by following the spirit of Netty.
Several composable channel pipeline components are provided.
may need an entity
and that can be tricky. Since a Jakarta RESTful Web Services
application may block whatever thread it is running on for some time
(for example, perhaps it is performing synchronous database access
over a slow connection), then normally it should be run on its own
thread that is not the Netty event loop. But assuming that is so, the
InputStream it will receive by way of a
will now be operated on by two threads: the application-hosting
thread, and the Netty event loop. microBean™ Jersey Netty Integration
ensures that this
InputStream implementation is thread-safe, uses as
few locks as possible, allocates as little memory as possible, and
takes advantage of
and other Netty native constructs to ensure this inter-thread
messaging is safe and efficient.
ContainerRequest needs a
which is responsible for actually writing the Jakarta RESTful Web
Services application's output. microBean™ Jersey Netty Integration
ContainerResponseWriter implementation that is also a
ContainerRequests as input, installs itself as their
ContainerResponseWriter implementation, and writes the requisite
output back to the channel safely and efficiently.
OutputStream implementation used to do this must, of course,
ensure that writes take place on the Netty event loop. microBean™
Jersey Netty Integration ensures that this
does not needlessly buffer and/or copy
byte arrays but instead takes
advantage of the built-in outbound event queuing present in the Netty
event loop itself.
Similar constructs are provided for HTTP/2 support as well.