{"id":23095023,"url":"https://github.com/microbean/microbean-jersey-netty","last_synced_at":"2025-09-25T20:11:38.283Z","repository":{"id":56000653,"uuid":"190290105","full_name":"microbean/microbean-jersey-netty","owner":"microbean","description":"A Java library that integrates Jersey into Netty idiomatically.","archived":false,"fork":false,"pushed_at":"2021-05-05T18:24:35.000Z","size":3717,"stargazers_count":5,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-28T12:46:50.701Z","etag":null,"topics":["java","java-library","jersey","microbean","netty"],"latest_commit_sha":null,"homepage":"https://microbean.github.io/microbean-jersey-netty/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/microbean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-04T22:50:49.000Z","updated_at":"2024-03-31T14:22:36.000Z","dependencies_parsed_at":"2022-08-15T11:10:23.317Z","dependency_job_id":null,"html_url":"https://github.com/microbean/microbean-jersey-netty","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/microbean/microbean-jersey-netty","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microbean%2Fmicrobean-jersey-netty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microbean%2Fmicrobean-jersey-netty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microbean%2Fmicrobean-jersey-netty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microbean%2Fmicrobean-jersey-netty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/microbean","download_url":"https://codeload.github.com/microbean/microbean-jersey-netty/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microbean%2Fmicrobean-jersey-netty/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276975609,"owners_count":25738503,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-25T02:00:09.612Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","java-library","jersey","microbean","netty"],"created_at":"2024-12-16T22:19:15.622Z","updated_at":"2025-09-25T20:11:38.240Z","avatar_url":"https://github.com/microbean.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# microBean™ Jersey Netty Integration\n\n[![Build Status](https://travis-ci.com/microbean/microbean-jersey-netty.svg?branch=master)](https://travis-ci.com/microbean/microbean-jersey-netty)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.microbean/microbean-jersey-netty/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.microbean/microbean-jersey-netty)\n\nThe microBean™ Jersey Netty Integration project integrates\n[Jersey](https://jersey.github.io/) into [Netty](https://netty.io) in\nan idiomatic way.\n\nJersey can be run as a simple handler of sorts in a [Netty\npipeline](http://tutorials.jenkov.com/netty/netty-channelpipeline.html).\nThe Netty event loop remains unblocked, there is no locking, reads and\nwrites involve minimal copying of byte arrays, output is streamed\nwhere appropriate and it is intended that there be as few object\nallocations as possible.\n\nHTTP 1.1 and HTTP/2 are both supported, including upgrades via [HTTP's\nupgrade\nheader](https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#header.upgrade),\n[ALPN](https://www.rfc-editor.org/rfc/rfc7301#page-2) or [prior\nknowledge](https://http2.github.io/http2-spec/#known-http).\n\n## Status\n\nThis project uses [semantic versioning](https://semver.org/).  It is\nstill in an alpha state.\n\n## Installation\n\nAdd a dependency on this project in your Netty-based Maven project:\n\n```\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.microbean\u003c/groupId\u003e\n  \u003cartifactId\u003emicrobean-jersey-netty\u003c/artifactId\u003e\n  \u003c!-- Always check\n  https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.microbean%22%20AND%20a%3A%22microbean-jersey-netty%22\n  for the latest available version. --\u003e\n  \u003cversion\u003e0.25.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Usage\n\nTo use, install an instance of\n[`JerseyChannelInitializer`](https://microbean.github.io/microbean-jersey-netty/apidocs/org/microbean/jersey/netty/JerseyChannelInitializer.html)\nas the [child\nhandler](https://netty.io/4.1/api/io/netty/bootstrap/ServerBootstrap.html#childHandler-io.netty.channel.ChannelHandler-)\nof a Netty\n[`ServerBootstrap`](https://netty.io/4.1/api/io/netty/bootstrap/ServerBootstrap.html):\n\n    serverBootstrap.childHandler(new JerseyChannelInitializer(baseUri, // e.g. URI.create(\"/\")\n        sslContext, // an SslContext, or null if you don't want TLS support\n        true, // yes, HTTP/2 support please\n        20971520L, // 20MB maximum incoming payload (arbitrary)\n        new DefaultEventExecutorGroup(8), // a DefaultEventExecutorGroup with 8 threads (arbitrary) to run your application\n        true, // yes, use Jersey's native dependency injection facilities\n        new ApplicationHandler(yourJaxRsApplication), // the ApplicationHandler wrapping your application\n        8192, // write in 8K chunks (arbitrary)\n        Unpooled::new /* how to create those chunks */));\n\n## Background and Motivation\n\nWhile Jersey itself contains a [Netty integration\nproject](https://github.com/eclipse-ee4j/jersey/tree/master/containers/netty-http),\nit is annotated with\n[`@Beta`](https://eclipse-ee4j.github.io/jersey.github.io/apidocs/latest/jersey/org/glassfish/jersey/Beta.html),\nand the author additionally\n[writes](https://github.com/eclipse-ee4j/jersey/blob/8dcfed4836d26c57ef78be68214d186e9ca78b84/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyHttp2ServerHandler.java#L50)\nthat his \"implementation cannot be more experimental\".  In addition,\nthere are several issues with the Jersey-supplied Netty integration\nproject.  The most problematic seems to be [issue\n3500](https://github.com/eclipse-ee4j/jersey/issues/3500).  This issue\nand others stem from the fact that the Jersey-supplied Netty\nintegration project sets up its own internal queues for streaming,\nwhich overflow.  Additionally, new `ByteBuffer`s and `InputStream`s\nare allocated throughout.  It is also not entirely clear if HTTP/2 is\nfully supported.\n\nRecently, [there have been some efforts to improve this\narea](https://github.com/eclipse-ee4j/jersey/commit/8dcfed4836d26c57ef78be68214d186e9ca78b84),\nbut they still do not take advantage of the built in queuing and\nthreading constructs offered up by Netty itself.\n\n## Implementation Details\n\nBy contrast, microBean™ Jersey Netty Integration approaches the\nproblem of running a Jakarta RESTful Web Services application under\nNetty by following the spirit of Netty.\n\nSeveral composable channel pipeline components are provided.\n\nConsidering HTTP 1.1 support, the first is a\n[_decoder_](https://netty.io/4.1/api/io/netty/handler/codec/MessageToMessageDecoder.html)\nthat decodes\n[`HttpRequest`](https://netty.io/4.1/api/io/netty/handler/codec/http/HttpRequest.html)\nand\n[`HttpContent`](https://netty.io/4.1/api/io/netty/handler/codec/http/HttpContent.html)\nmessages into\n[`ContainerRequest`](https://eclipse-ee4j.github.io/jersey.github.io/apidocs/latest/jersey/org/glassfish/jersey/server/ContainerRequest.html)\nobjects, which are the objects consumed natively by Jersey.\n\nA\n[`ContainerRequest`](https://eclipse-ee4j.github.io/jersey.github.io/apidocs/latest/jersey/org/glassfish/jersey/server/ContainerRequest.html)\nmay need an [entity\nstream](https://eclipse-ee4j.github.io/jersey.github.io/apidocs/latest/jersey/org/glassfish/jersey/server/ContainerRequest.html#setEntityStream-java.io.InputStream-),\nand that can be tricky.  Since a Jakarta RESTful Web Services\napplication may block whatever thread it is running on for some time\n(for example, perhaps it is performing synchronous database access\nover a slow connection), then normally it should be run on its own\nthread that is not the Netty event loop.  But assuming that this is\nso, the `InputStream` it will receive by way of a\n[`ContainerRequest`'s entity\nstream](https://eclipse-ee4j.github.io/jersey.github.io/apidocs/latest/jersey/org/glassfish/jersey/server/ContainerRequest.html#setEntityStream-java.io.InputStream-)\nwill now be operated on by two threads: the application-hosting\nthread, and the Netty event loop.  microBean™ Jersey Netty Integration\nensures that [this `InputStream`\nimplementation](https://microbean.github.io/microbean-jersey-netty/apidocs/org/microbean/jersey/netty/TerminableByteBufInputStream.html)\nis thread-safe, uses as few locks as possible, allocates as little\nmemory as possible, and takes advantage of\n[`CompositeByteBuf`](https://netty.io/4.1/api/io/netty/buffer/CompositeByteBuf.html)\nand other Netty native constructs to ensure this inter-thread\nmessaging is safe and efficient.\n\nSimilarly, a `ContainerRequest` needs a\n[`ContainerResponseWriter`](https://eclipse-ee4j.github.io/jersey.github.io/apidocs/latest/jersey/org/glassfish/jersey/server/spi/ContainerResponseWriter.html#writeResponseStatusAndHeaders-long-org.glassfish.jersey.server.ContainerResponse-)\nwhich is responsible for actually writing the Jakarta RESTful Web\nServices application's output.  microBean™ Jersey Netty Integration\nprovides a `ContainerResponseWriter` implementation that is also a\n[`ChannelInboundHandlerAdapter`](https://netty.io/4.1/api/io/netty/channel/ChannelInboundHandlerAdapter.html):\nit takes `ContainerRequest`s as input, installs itself as their\n`ContainerResponseWriter` implementation, and writes the requisite\noutput back to the channel safely and efficiently.\n\nThe `OutputStream` implementation used to do this must, of course,\nensure that writes take place on the Netty event loop.  microBean™\nJersey Netty Integration ensures that [this `OutputStream`\nimplementation](https://microbean.github.io/microbean-jersey-netty/apidocs/org/microbean/jersey/netty/ByteBufBackedChannelOutboundInvokingHttpContentOutputStream.html)\ndoes not needlessly buffer and/or copy `byte` arrays but instead takes\nadvantage of the built-in outbound event queuing present in the Netty\nevent loop itself.\n\nSimilar constructs are provided for HTTP/2 support as well.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrobean%2Fmicrobean-jersey-netty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicrobean%2Fmicrobean-jersey-netty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrobean%2Fmicrobean-jersey-netty/lists"}