Jersey 2.37, 3.0.8, and 3.1.0-M8

Jersey project continues to develop three branches, Java EE / Jakarta EE 8 – Jersey 2.x, Jakarta EE 9 – 3.0.x, and the new Jakarta EE 10 – 3.1.x. Recently, Jersey 2.37, and 3.0.8 were released. Jersey 3.1.0-M8 is still a milestone release, although very close to the final. Only a few dependencies are not final, yet, and Jersey 3.1 keeps releasing milestones in the meantime.

These releases bring a couple of new features. The full list of the features and updates can be found in multiple locations. They are the Eclipse Jersey project home page, Jersey GitHub wiki page, and the usual GitHub Releases link describing a list of commits.

Jersey started to support Gson, the Google JSON library, as a reaction to multiple customer requests. Jersey supports multiple JSON frameworks already, such as Jackson, Jettison, Moxy, and mainly Json Binding/Yasson. With recent Jersey, Gson adds to the list with the following dependency:


Jersey also supports CompletionStage<Response> as a resource method return type.

A significant amount of work has been done on Connectors:

  • In a previous Jersey release, Apache HTTP 5 Client connector was introduced.
  • Currently, proxy support has been fixed in the Netty connector.
  • The default HttpUrlConnector supports ClientProperties.PROXY_URI, PROXY_USERNAME, PROXY_PASSWORD, as well as the system http.proxyHost property.
  • Jetty connector supports a new TOTAL_TIMEOUT property.
  • Jersey 3.1.0 supports new JDK 11 (jnh) HTTP client based connector (jersey-jnh-connector).
  • In a previous 3.0.x release, Jersey brought back support for Helidon Connector (JDK 17+ only) based on Helidon 3, which supports Jakarta EE 9/MicroProfile 5.

MicroProfile 5 comes with Jakarta EE 9 support, which allows Jersey 3 for being compliant with MP RestClient 3, and MP Config 3 support can be used (Both Helidon 3 Config helidon-microprofile-config on JDK 17+ or SmallRye Config smallrye-config on JDK 11+ can be used) for Jersey 3.

Jersey 3 also introduced Spring 6 support for JDK 17+ (Spring 6 supports Jakarta EE!) and Jersey provides two examples helloworld-spring-webapp and helloworld-spring-annotations.

As always, give new Jersey a try and let us know how you like it.

Posted in Jersey | Comments Off on Jersey 2.37, 3.0.8, and 3.1.0-M8

Jersey 3.1.0 – Incompatibilities and changes

This article discusses backward-incompatible changes in Jersey 3.1.0. While Jersey tries to minimize these incompatible changes, the changes are forced by the Platform Specification Project, API project, security reasons, or an unstoppable evolution.

Jersey 3.1.0 drops compatibility with JDK 8.

Jakarta EE 10 defines a minimum JDK 11 runtime to be supported and many Jakarta EE 10 APIs and their implementations will drop JDK 8 support, too. Only Jersey 2.x will continue supporting JDK 8. The JDK version support in Jakarta EE was decided during a community vote, and many community members supported JDK 17 as a minimum JDK version. While it looks like a big jump forward, it is possible that JDK 17 will become the minimum supported JDK version in Jakarta EE 11, which should come next year.

The default HttpUrlConnector no longer supports HTTP Patch on JDK 16+.

The default HttpUrlConnection supports only HTTP 1.1 request methods. Other methods, such as HTTP Patch, are not supported by the HttpUrlConnection and Jersey overcomes the issue using reflection, if configured using the SET_METHOD_WORKAROUND property, for instance:, true)

Starting with JDK 16, reflection on JDK internal classes is not allowed, and HTTP Patch can no longer be used with the default HttpUrlConnector. This applies to Jersey 2.x, 3.0.x, too, but it is worth mentioning it here.

One solution is to use any other Jersey connector.

Another solution is to use the X-HTTP-Method-Override HTTP header.

Please be aware of possible exploits.

The uncaught exception is never propagated to the underlying I/O container.

Jakarta REST 3.1 defines a new requirement for a default ExceptionMapper<Object> so that the Exception is never propagated to the Servlet Container or any other container Jersey integrates with. This is important for frameworks integrating Jersey. The exception is still logged, and users will see the exception in the (server) log as they are used to.

No Jackson 1 support.

Jackson 1 support is dropped in Jersey 3.1.0. Jackson 1 is unmaintained for some time, and Jackson 2 is recommended to be used.

GitHub repository change

The historical Jersey (pre-Eclipse) repository was moved from to and the repository is read-only.

The current repository is located at However, since all projects are asked to move from eclipse-ee4j GitHub organization to jakartaee GitHub organization, the current repository URL can change in the future. Similarly, the Jakarta REST API GitHub repository moved from to Fortunately, the redirect works well.

Jersey GitHub master branch will no longer contain Jersey 2.x.

The repository uses several branches, master is used for 2.x, 3.x is used for 3.0.x, branch 3.1 is used for 3.1.x releases. The current plan is to use master for the latest development, similar to other projects.

Documentation URL

The original Jersey documentation has been accessible from The URL still provides a redirect to the current documentation website.

While Jersey 2.x used URI, Jersey 3.0.x uses

This possibly changes two ways. First, the prefix will change because of the GitHub repository change discussed above. Second, the latest/index.html will be used for the documentation of the highest Jersey version. Jersey 2.x documentation will be in latest2x/index.html.

Changes in processing JAX-RS code by Jersey

Since Jersey 3.1.0, ClientRequest#getRequestHeader(String) returns null instead of an empty list in case the specified header does not exist. This change is a reflection of the Jakarta REST requirement coming with the new Specification.

Another change comes with a resource method returning CompletionStage, for instance

public CompletionStage<List<String>> getMethod() {...}

In Jersey 2.x, the message body provider receives entity type CompletionStage<List<String>>, which is not properly handled by most entity providers. The property ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE set to true ensures List<String> is passed to the message body provider. In Jersey 2.x, it is kept like this for backward compatibility with older Jersey versions. Jersey 3.1.0 sets the default value of this property to true, and the List<String> is passed to providers by default, as would be expected.

Deprecated Application#getSingletons()

Jakarta REST 3.1 deprecates Application#getSingletons() which can cause warnings with the older applications.


There are minor incompatibility changes coming with the Jersey 3.1.0 release. But we believe the changes impact the Jersey customers only by a minimum. As always, if you have any concerns, let us know on our issue tracker.

Posted in Jersey | Comments Off on Jersey 3.1.0 – Incompatibilities and changes

Jersey 3.1.0-M3 has been released!

Jersey 3.1.0-M3 is Jakarta RESTful Web Services 3.1 compatible implementation. And we are happy to announce that it has been finally released to maven central.

Jakarta REST 3.1 Specification is a part of Jakarta EE 10, which will be released in June 2022.

What’s next?

Jersey 3.1.0 final will be released as soon as all the required EE 10 dependencies are out in the maven central.

Along with Jersey 3.1.0, also Jersey 3.0.5 (Jakarta EE 9 compatible) and Jersey 2.36 (Jakarta EE 8 compatible) will be released. Jersey 2.x, (EE8), and Jersey 3.0.x (EE9) will continue to be released in alignment with Jersey 3.1.x (EE 10) – the new features and fixes come to as many branches as possible.

Jakarta EE 11

For Jakarta EE 11, Jakarta REST 4.0 and Jersey 4.0 are planned. Jersey 4.0 shall bring support for both CDI full and CDI light, which would become the main DI in the framework.

Hope you enjoy

As always, we would like to hear from you how you like Jersey. For any particular issues or enhancement requests, please feel free to use the Jersey issue tracker.

Posted in Jersey | Comments Off on Jersey 3.1.0-M3 has been released!

Jersey 2.35, and Jersey 3.0.3

Jersey 2.35 and corresponding Jersey 3.0.3 have been released recently. There is a number of new features.

We support JDK 17, JDK 16, JDK 15, JDK 14, JDK 13, JDK 12, JDK 11, and JDK 8. It means, Jersey is tested there, passes tests, and is perfectly functional. Except… It does not mean we support JDK 16 records. It does not mean we use JPMS and define the module-infos. It does not mean HTTP Patch requests work with the default HttpUrlConnector on JDK 16. But we are working on these features, too.

We support the Graal VM native image (please read the documentation and try our example). We support Optional<T> in the HTTP request parameters (QueryParam, PathParam,…). We implement MP Rest Client 2.0 (we are also compatible with MP Rest Client 1.4 API).

But mainly, we make progress towards Jakarta REST 3.1, and Jakarta REST 4.0.

Jakarta REST 3.1 brings a requirement that Feature and Dynamic Feature must be possible to define as a JDK service (by adding provider-configuration file) and it is loaded by the implementation. We allow this feature in Jersey 2.35 and 3.0.3, too.

Jakarta REST 3.1 introduces MultiPart API. Jersey supports MultiPart already, using Jersey API. We added support of RFC 5987 filename attributes.

The most important change planned for Jakarta REST 4.0 is the mandatory CDI integration. JAX-RS 2.0 introduced optional CDI integration: In a product that supports CDI, implementations MUST support the use of CDI-style Beans as root resource classes, providers and Application subclasses. Jakarta REST 3.1 deprecates @Context annotation: Note that future versions of this API will stop supporting injection via @Context as part of a tighter integration and alignment with Jakarta CDI.

Jersey 2.34 introduced a new module org.glassfish.jersey.ext.cdi:jersey-cdi-rs-inject, which enables injecting Jakarta REST injectables normally injected by @Context to be injected using @Inject, when using CDI. It is enough just to add the module to a classpath. This is one step towards pure CDI injection.

Jersey 2.35 introduced an experimental module org.glassfish.jersey.incubator:jersey-cdi-inject-weld. This module implements an InjectionManager that is completely CDI-based, with no HK2 involved. Currently, it works just with the jersey core modules, and we have an example that shows the module working (when running with “CdiInjectWeld” profile). This module will definitely be a subject of changes in the future. The current plan is to support CDI lite and CDI lite can be a reason for the complete redesign of the module. CDI lite, as well as CDI 4.0, is a subject for Jakarta EE 11, and the details of the changes are not known, yet.

Soon, Jakarta REST 3.1 release candidate will be released, and the first milestone release of Jersey 3.1.0 will follow. These artifacts are part of Jakarta EE 10 which is finishing and will go through a release review ballot; Jakarta EE 10 will be out during this winter.

Posted in Jersey | Comments Off on Jersey 2.35, and Jersey 3.0.3

Very Merry Christmas with Jersey 2.33

Jersey 2.33 is out! As usually, right before Christmas we put together as many fixes and new features as possible to deliver new Jersey for you, the Jersey customers.

During the work on Jersey 2.33, we already delivered Jersey 3.0.0, which kept us busy, and there not as many changes as usual for a regular release. Jersey 2.33 contains mainly fixes and we were thinking about a service 2.32.1 release.

There is one significant change in Jersey 2.33, however. We decided to make JAX-B API optional. When there is JAX-B API among dependencies on the classpath, it works as ever. However, if it is not there, Jersey prints a warning, but would not fail. Please make sure you add the JAX-B dependency if you need it, from now on.

We decided on this for multiple reasons. We register requests for this change from microservices guys who try to make the application the smallest possible and they do not use JAX-B or WADL. They also customize their JDK not to contain javax.xml and javax.awt modules and we made them optional. And it is the future of Jakarta RESTful Web Services, too. The next version of the Specification will mandate the JAX-B dependency optional.

For the complete list of changes, check the Jersey 2.33 release details. As always, we are happy to hear your feedback. If any issue is found, contact us on our issue tracker, or just send us an email about how you like Jersey.

Posted in Jersey | Comments Off on Very Merry Christmas with Jersey 2.33

Happy Jakarta EE 9 with Jersey 3.0.0

Jakarta EE 9 and Jersey 3.0.0 are here. The transition to a new jakarta package based APIs took a great amount of work, from the whole Jakarta EE community. It started in the spring of the year 2020, and finally, Jakarta EE 9 is almost there! There are just a few missing bits not yet released to maven central coming very soon!

Jersey 3.0.0 pre-releases and dependencies

Jersey is split into many modules which has a dependency on so many APIs and their respective implementations, JAX-RS, JAX-B, JSON-P, JSON-B, Servlet, JSP, EJB, HK2, CDI, Bean Validation, Inject, Interceptor, … All of these projects did all necessary work to be transitioned to Jakarta EE 9, and it has been possible to get Jersey 3.0.0. released to maven central, eventually.

Jersey 3.0.0 has few milestone releases. Each milestone release adopted a new subset of Jakarta EE 9 APIs, and finally, we were able to pass Jakarta EE 9 RESTful Web Services TCK with Jersey 3.0.0-M6. Since then, we marked the releases as release candidates.

Jersey 3.0.0 final has several dependencies not yet final, some are release candidates, but some are beta (Weld), or even alpha (Hibernate Validator). All the Jakarta EE 9 API dependencies are final, however!

How to try

Feel free to try Jakarta EE 9 and Jersey 3.0.0. It is available either as a part of Glassfish 6.0.0 (RC1 and RC2 are available in maven central, and Glassfish 6.0.0 final is on its way), or standalone in maven central, as usual.

Changes to Jersey 2.x

Jersey 3.0.0 keeps most of the Jersey 2.x features. It is still able to support Jackson 2 (we dropped the obsolete Jackson 1 support), see the examples. We also keep supporting the MicroProfile Config. Jersey 3.0.0 does not support the MicroProfile REST client, however, since it has a strong JAX-RS 2.1 dependency. We also dropped the Helidon Connector module for the time being.

Jersey 3.0.0 uses Jetty in many tests and examples. Compatible Jetty 11 dropped support of JDK 8, hence those examples and tests require JDK 11+ to run.

Contact us

Jakarta EE 9 is backward incompatible with Jakarta EE 8. We tried to keep most features and functionality the way it is in Jersey 2.x to ease a transition of applications to Jakarta EE 9. The API package name is still a huge change and if any issue is found, contact us on our issue tracker, or just send us an email about how you like Jersey.

Posted in Jakarta EE, Jersey | Comments Off on Happy Jakarta EE 9 with Jersey 3.0.0

Understanding Jakarta EE 9


Java Enterprise Edition, or Java EE, is a set of standards defined to be used in an enterprise environment, implemented by a set of Java EE compatible application servers. Java Enterprise Edition or JEE (formerly Java 2 Enterprise Edition, or J2EE) is being developed for more than a decade, starting with the first J2EE 1.2 release in 1999. In 2017-2018, the entire Java EE was contributed to the Eclipse Foundation, and it is known as Jakarta EE now.

There are 3 known releases of Jakarta EE, each with a different variation of maven coordinates and java package name. The first has been announced in January 2019. It was a technical release, almost identical to Java EE 8, and it was marked by a code name EE4J_8 (every Jakarta EE/EE4J project used to have a git branch with this code name). It was a release to prove that the Java EE contributed code is complete. This release was not Jakarta EE release, yet. The APIs used javax maven coordinates (for instance and javax java package name (for instance

The second release is known as Jakarta EE 8 release. The APIs in Jakarta EE 8 use jakarta maven coordinates (for instance, but the javax java package name ( Jakarta EE 8 is (99.9%) backward compatible with Java EE 8.

The third, very soon upcoming release, is known as Jakarta EE 9. The APIs in Jakarta EE 9 use jakarta maven coordinates (for instance, but the java package name has been changed to jakarta (

Jakarta EE 9 hence is NOT BACKWARD COMPATIBLE with Java EE 8!


  • Every API needs to transition the java package from javax to jakarta.
  • Every Specification needs to get updated to reflect the new API changes.
  • Every implementation of a respective Specification needs to be adjusted to handle the new APIs.
  • New versions of application servers need to be released. Many Specifications are involved for instance with the Servlet container and/or CDI and therefore the new implementations won’t work on the old (Java EE-based) application servers, and the old implementations won’t work on the new (Jakarta EE 9-based) application servers.
Jersey 3 needs Jakarta EE 9-based server, such as Glassfish 6, Jetty 11, Tomcat 10!
Jersey 2 needs Java EE 8/Jakarta EE 8-based server, such as Glassfish 5, Jetty 9/10, Tomcat 9!
  • For the java package name change, Jakarta EE 8 API does not work with Jakarta EE 9 implementation and vice versa.
  • In cases, when both the Java EE API would be needed (such as when using JAX-B API with Jackson), and Jakarta EE 9 API would be needed (for other JAX-B usages), mixing Jakarta EE 8 and Jakarta EE 9 API would cause issues with maven (since both use the same maven coordinates). Instead of Jakarta EE 8 jars, the older Java EE 8 jars would better be used.
Do not mix Jakarta EE 8 and Jakarta EE 9 artifacts!

Jakarta EE 9 / EE4_J artifacts

It is not very easy to recognize Jakarta EE9 APIs and compatible implementations. It’s the artifact versions that matter. To name some:

  • jakarta.activation:jakarta.activation-api:2.0.0 + com.sun.activation:jakarta.activation:2.0.0
  • jakarta.annotation:jakarta.annotation-api:2.0.0
  • jakarta.authentication:jakarta.authentication-api:2.0.0
  • jakarta.authorization:jakarta.authorization-api:2.0.0
  • jakarta.batch:jakarta.batch-api:2.0.0 +*:2.0.0
  • jakarta.ejb:jakarta.ejb-api:4.0.0
  • jakarta.enterprise:jakarta.enterprise.cdi-api:3.0.0 +*:4.0.0
  • jakarta.enterprise.concurrent:jakarta.enterprise.concurrent-api:2.0.0
  • jakarta.el:jakarta.el-api:4.0.0
  • jakarta.faces:jakarta.faces-api:3.0.0 + org.glassfish:jakarta.faces:3.0.0
  • jakarta.inject:jakarta.inject-api:2.0.0
  • jakarta.interceptor:jakarta.interceptor-api:2.0.0
  • jakarta.jms.jakarta.jms-api:3.0.0
  • jakarta.json:jakarta.json-api:2.0.0 + org.glassfish:jakarta.json:2.0.0
  • jakarta.json:jakarta.json.bind-api:2.0.0 + org.eclipse:yasson:2.0.0
  • jakarta.jws:jakarta.jws-api:3.0.0
  • jakarta.mvc.jakarta.mvc-api:2.0.0 + org.eclipse.krazo:*:2.0.0
  • jakarta.persistence:jakarta.persistence-api:3.0.0 + org.eclipse.persistence:*:3.0.0
  •**:*:2.0.0 + org.glassfish.soteria:*:2.0.0
  • jakarta.servlet:jakarta.servlet-api:5.0.0
  • jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.0.0
  • jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:2.0.0
  • jakarta.transaction:jakarta.transaction-api:2.0.0
  • jakarta.validation.jakarta.validation-api:3.0.0 + org.hibernate.validator:hibernate-validator:7.0.0
  • jakarta.websocket:jakarta.websocket-api:2.0.0 + org.glassfish.tyrus:*:2.0.0
  • + org.glassfish.jersey:*:3.0.0
  • jakarta.xml.bind:jakarta.xml.bind-api:3.0.0 + com.sun.xml.bind:*:3.0.0
  • + com.sun.xml.*:*:3.0.0

The list goes on, especially for every Jakarta EE 9 compatible implementation from various vendors.

The artifacts are not available in maven central

The artifacts are not available in maven central, yet. Some of them are, in the milestone version (Jersey 3.0.0-M6), some in Alpha, or Beta (Bean Validation implementation, Weld), some in release candidate versions (EJB API), some in the final version (CDI API) but one day, it will all be there.

The final versions of the APIs/Specifications go through so-called ballots, and once the ballot is approved, it can be released to maven central. Then, when other technologies have all the dependencies gone through the ballots, they can go through the ballots as well. The ballots are processed in waves, and October 2020 is the most active month regarding the ballots to get Jakarta EE 9 released on November 20.

Jakarta EE 9 is finishing to be released on November 20.

The progress on Jakarta EE 9 can be viewed by observing Glassfish 6 weekly builds. While the Jakarta EE 9 bits may not be available in maven central, yet, Glassfish 6 may already integrate them. For Jersey and Tyrus, the milestone versions are available in maven central, since all used dependencies are available in maven central, too. Glassfish contains release candidates, that are not available in maven central, yet, and they will get there once the dependencies are there. We mark them as release candidates since the final version of the Jakarta Restful Web Services API / Jakarta WebSocket API is referenced. As soon as all the TCKs are passing, the release candidate of Glassfish is planned. The Glassfish is not tested on JDK 11, or newer, yet.

The initial Jakarta EE 9 is required just to work on JDK 8.

Jakarta EE 9.1 is planned very soon after the initial release, and it will be compatible with JDK 11 (as well as with JDK 8).

What happened with JAX-RS acronym

Java API for RESTful Web Services (JAX-RS) continues as Jakarta Restful Web Services. To distinguish between Java EE and Jakarta EE, Jakarta Restful Web Services stopped using the JAX-RS acronym. The acronym is no longer used in the Specification document, nor in the API, nor the TCK document. The full Jakarta Restful Web Services name is used there instead. The discussion about a better acronym/abbreviation did not find a final replacement, yet. The most favorable seems to be Jakarta REST, but people keep using the JAX-RS acronym during a discussion.

The full Jakarta Restful Web Services name is prefered over JAX-RS acronym for the time being to distinguish between Java EE and Jakarta EE.
Posted in Jakarta EE, Jersey | Comments Off on Understanding Jakarta EE 9

What is new in Jersey 2.32

Recently, Jersey 2.32 has been released. Jersey 2.x is a continuous evolution of Jersey implementing JAX-RS 2.1 Specification. While the successor Jakarta Restful Web Services 3.0 Specification, which is part of the Jakarta EE 9 initiative, will bring a lot of new features that will be implemented in Jersey 3.x (currently in 3.0.0-M6 release – which passes the Jakarta EE 9 Restful Web Services TCK already), and Jersey 3.x will become the main evolution branch, we see many requirements to keep developing Jersey 2.x for several additional years.

Jersey 2.32 (or newer) is the JAX-RS implementation that is going to be used in Helidon 2.0.3, and it also is planned to be part of the Weblogic Application Server 14.1.2.

Jersey 2.32 supports JDK 8, and JDK 11-JDK 15 (since Jersey 2.31). Along with interfaces PreInvocationInterceptorPostInvocationInterceptor, and InvocationBuilderListener, introduced in Jersey 2.30, an additional ClientBuilderListener interface has been added. Unlike the first two, it is not registered on the client, rather it is used as a service (defined in META-INF/services) so that it can be invoked before the Client is created.

Helidon 2 comes with a new reactive HTTP client called WebClient based on Netty HTTP client. Jersey 2.31 came with an alternative connector that uses the Helidon WebClient for HTTP requests using the WebClient by JAX-RS/Jersey client syntax. It has been built using Helidon 2.0.0-RC2 and as with the other connectors. The Helidon API changed, however, between Helidon 2.0.0-RC2 and Helidon 2.0.0 and the connector implementation was contributed to Helidon. Hence Jersey 2.32 comes with HelidonConnectorProvider that simply reuses the connector from Helidon. This way, the connector reflects the most recent changes in the implementation in Helidon (we recommend to use with Helidon 2.0.3, or later, when available, the maven dependency on Helidon connector is therefore provided in Jersey Helidon Connector module).

We made improvements to Netty and Apache connector, too. The Netty connector is configurable using NettyClientProperties, Apache connector accepts HttpEntity type in JAX-RS Entity. The default HttpUrlConnector now supports Expect:100-continue HTTP header using Expect100ContinueFeature.

Registering features now supports priorities on features. Both using @Priority or register(feature, priority) are legitimate options. This allows for the ordering of the execution of the features.

MicroProfile Rest Client implementation is now compatible with MicroProfile Rest Client 1.4.1 Specification. It also allows for using regular expressions in @Path annotation now.

We modified SSE, so now it is possible to do all of the following (in case of JDK8 the last 2 lines are not applicable):

    public void register(@Context SseEventSink eventSink)
    public void register(@Context org.glassfish.jersey.internal.jsr166.Flow.Subscriber<String> eventSink)
    public void register(@Context org.glassfish.jersey.internal.jsr166.Flow.Subscriber<OutboundEvent> eventSink)
    public void register(@Context java.util.concurrent.Flow.Subscriber<String> eventSink)
    public void register(@Context java.util.concurrent.Flow.Subscriber<OutboundEvent> eventSink)

For additional changes and details, it is possible to check release 2.32, and 2.31, respectively.

Posted in Jersey | Comments Off on What is new in Jersey 2.32

Jersey 2.30.1 has been released

It has been a while since we have released Jersey 2.30. On the client-side, we introduced new PreInvocationInterceptorPostInvocationInterceptor, and InvocationBuilderListener interfaces. We made the default Rx client using the AsyncInvoker (unlike the RxInvokerProvider). We worked hard to make the Apache HttpClient Connector working with the new Apache Http Client as fine as the old days. We allowed the MP REST Client to work with any Jersey connector.

On both the client and server-side, we allowed the HeaderDelegateProvider to work again. We improved the integration with CDI. We allow some of the default AWT and/or XML related providers to be disabled. The full change list can be observed here.

Mainly, we created a multi-release jar for our WADL doclet extension, which works with JDK 13. So Jersey 2.30 is the first release that is fully buildable and works on JDK 13. Hurray!

Unfortunately, we made the release with JDK 12, and the 2.30 multi-release core-common jar now contains byte code for JDK 8, and for JDK 12+.

Jersey 2.30.1 mainly fixes the bug for the core-common multi-release jar, which works with JDK11, again (the same as Jersey 2.29.1). Other fixes and improvements were put in. We improved the integration with the Netty client and server. We better handle multiple cookies with the same name. We made a step towards Jersey being used in Glassfish 6. And we successfully made it through the Release Review.

For the next release, we continue to be working on Jersey 2.x, and we started to work on Jersey 3.x. Jersey 2.x continues to be compatible with JAX-RS 2.1.6 API, and we plan to keep it working with JDK 8, JDK 11, JDK 12, JDK 13, and we also plan to support JDK 14 as soon as possible. Jersey 3.x will be compatible with Jakarta RESTful WebServices 3.x.y API, which no longer uses java package, but it moves to package, similarly to all Jakarta EE 9 projects. Jersey 3.0.0 still will work with JDK 8, but it is possible that Jakarta RESTful WebServices API 3.1.0 or later will require JDK 11 features, and at that point, the backward compatibility with JDK 8 can be abandoned by Jersey 3.x.

Posted in Jersey | Comments Off on Jersey 2.30.1 has been released

New Features in Jersey Client

Jersey 2.30 comes with multiple new features, and this post describes three new interfaces on the client. They are PreInvocationInterceptor, PostInvocationInterceptor, and InvocationBuilderListener.

Suppose a case that the start of the request is to be logged and even measured. This can be done by ClientRequestFilter, which is usually invoked before the request is wired on the network. However, the filter may be called as a last of the filters in the chain. Sure, it can have the highest priority, but the other filters can have the very same priority! Some long-running operations can be performed before the measuring can actually start. Even worse, the filter may even be skipped from the chain by the previous #abortWith!


For this, PreInvocationInterceptor, the code that executes before the ClientRequestFilters are invoked, has been added to the client request chain. Jersey ensures all the interceptors are invoked with each request. The interceptor contains a single #beforeRequest method, which corresponds to ClientRequestFilter:

     * The method invoked before the request starts.
     * @param requestContext the request context shared with
     * ClientRequestFilter.

   void beforeRequest(ClientRequestContext requestContext);

Note that only a single #abortWith is allowed in all PreInvocationInterceptors, otherwise an IllegalStateException is thrown. All the exceptions accumulated in PreInvocationInterceptors are thrown in a single Exception, available through #getSuppressed().


Similarly, ClientResponseFilter seems to be a good place where the total time of the HTTP request can be measured, but similarly to ClientRequestFilter, the response filter may not be invoked at all. For this, PostInvocationInterceptor has been introduced. Jersey runtime ensures that every PostInvocationInterceptor is called. Since an exception can occur during the HTTP request, PostInvocationInterceptor comes with two methods:

     * The method is invoked after a request when no
     * is thrown, or the Throwables are resolved
     * by previous PostInvocationInterceptor.
     * @param requestContext the request context.
     * @param responseContext the response context
     * of the original Response or response context
     * defined by the new resolving Response.

    void afterRequest(ClientRequestContext requestContext,
                      ClientResponseContext responseContext);

     * The method is invoked after a Throwable is caught
     * during the client request chain processing.
     * @param requestContext the request context.
     * @param exceptionContext the context available to handle the
     * caught Throwables.

    void onException(ClientRequestContext requestContext,
                     ExceptionContext exceptionContext);

The #afterRequest method is executed when no exception has been thrown during the HTTP request, #onException method is executed if the exception has been thrown during the request. It is possible to set a response in #onException, and the consecutive PostInvocationInterceptor will execute its #afterRequest method.

The measuring example can looks as follows, then:

String response = ClientBuilder.newClient().target("path")
new PreInvocationInterceptor() {
    public void beforeRequest(ClientRequestContext requestContext) {
        startTime = System.currentTimeMillis();
.register(new PostInvocationInterceptor() {
   public void afterRequest(ClientRequestContext requestContext,
                            ClientResponseContext responseContext) {
     logDuration(System.currentTimeMillis() - startTime);
   public void onException(ClientRequestContext requestContext,
                           ExceptionContext exceptionContext) {
     logDuration(System.currentTimeMillis() - startTime);


InvocationBuilderListener is an interface that is inspired by Microprofile REST Client RestClientBuilderListener and it contains a single method:

     * Whenever an Invocation.Builder is created, (i.e. when
     * WebTarget#request() is called, this method would be invoked.
     * @param context the updated InvocationBuilderContext.

    void onNewBuilder(InvocationBuilderContext context);

InvocationBuilderContext a subset of methods of the Invocation.Builder. It can be used to call the default values of the Invocation.Builder. Since it is invoked at the time Invocation.Builder is instantiated, any consequent calls of the Invocation.Builder‘s methods will replace the defaults set by the InvocationBuilderListener.

For instance, if all the HTTP requests should contain a custom HTTP header, there can be created a feature that would be registered on the client:

  public static class MyFeature implements Feature {
        public boolean configure(FeatureContext context) {
                     l.getHeaders().add("MY_HEADER", "MY_VALUE"));
            return true;

And More!

Jersey 2.30 comes with more new features on the client, most notably a possible hanging when using the Apache Client Connector has been fixed and the Microprofile Rest Client implementation has been allowed to use connectors.

Posted in Jersey | Comments Off on New Features in Jersey Client