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 by an unstoppable evolution.
Jersey 3.1.0 drops compatibility with JDK 8. Jakarta EE 10 defines 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 Content-Type is “application/octet-stream”. Jersey used to support relaxed @Consumes annotation matching, which used to be always matched when the HTTP request did not contain Content-Type header. For instance for the following resource:
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
@Path("/")
public class Resource {
@GET
public String get() {
return ...
}
}
An HTTP GET request without a media type is usually created by
webTarget.request(MediaType.TEXT_PLAIN_TYPE).get()
and it used to be always matched the resource method and the proper response was sent. In Jersey 3.1.0 the HTTP request without a Content-Type header is considered of application/octet-stream media type and the resource method is not matched, the response with status 415 is sent. This is a requirement of HTTP/1.1 RFC, Jakarta REST 3.1, and it is also potentially dangerous not to respect the @Consumes annotation. The solution is to add the Content-Type HTTP header:
webTarget.request(MediaType.TEXT_PLAIN_TYPE).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN).get()
Another solution is to keep using the relaxed @Consumes matching by using boolean property ServerProperties.EMPTY_REQUEST_MEDIA_TYPE_MATCHES_ANY_CONSUMES registered with the Application subclass:
new ResourceConfig(classes)
.property(ServerProperties.EMPTY_REQUEST_MEDIA_TYPE_MATCHES_ANY_CONSUMES, true);
The default HttpUrlConnector does no longer support HTTP Patch on JDK 16+. This applies to Jersey 2.x, 3.0.x, too. The default HttpUrlConnection supports only HTTP 1.1 request methods. Other methods, such as HTTP Patch, is not supported by the HttpUrlConnection and Jersey overcome the issue using reflection, if configured using the SET_METHOD_WORKAROUND property, for instance:
client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true)
Staring with JDK 16, reflection on JDK internal classes is not allowed, and Http Patch can no longer be used with the default HttpUrlConnector.
One solution is to use any other Jersey connector.
Another solution is to use X-HTTP-Method-Override HTTP header.
Please be aware of possible exploits
The uncaught exception is never propagated to the underlying I/O container.
Microprofile Rest Client 3.0.
No Helidon Client Connector.
No Jackson 1 support.
Jersey Property
Jersey documentation
Jersey GitHub master branch will no longer contain Jersey 2.x.
Focus on new features for Jersey 3.x.