Table of Contents
Jersey 2.41 starts to support Jackson 2.15 which comes with default limitations for the length of parsed text, numbers, and nesting depth. Jersey keeps the Jackson default value, but it allows to override the maximum length of parsed text using the MessageProperties.JSON_MAX_STRING_LENGTH property if needed.
Versions 2.38 introduces non-compatible change for dependency of Open Tracing. As soon as Open Tracing breaks compatibility between the 0.30.0 and the 0.33.0 versions in its API, and Jersey updates Open Tracing to the 0.33.0 version in the 2.38, for everyone who uses Open Tracing framework it is required to upgrade their dependencies to the 0.33.0 version of the Open Tracing respectively.
Versions 2.30+ do not introduce anything breaking, however version 2.29.1 has a major change which means migration of Jersey to Jakarta EE (8) platform thus all inner dependencies to APIs are migrated to jakarta EE maven coordinates. This also means that all dependencies which were taken from JDK as such (like JAXB etc.) are now external for JDK 1.8 (but for JDK 11+ they are external even in their Java EE form). So, for those who will migrate to versions of Jersey 2.29.1 or 2.30+ , a massive extension of dependencies being downloaded for the project build will occur. Also, there is extended support of JDKs - maximum compatibility with JDK 15 (including previous JDKs). And other major improvements and fixes which are described in details in release notes below.
Between versions of 2.26 and 2.29 there are no breaking changes in Jersey which could prevent smooth migration It is enough just to increase Maven (Gradle or any other) dependencies to a required version and all existing code shall work without modifications.
The most fundamental change in Jersey 2.26 and later is that all the modules (including the client module) are now being built with Java SE 8 and with 1.8 language level.
As a consequential change, one of the modules was dropped, the rx-client-jsr166e
.
This implementation relied on the
ConcurrentHashMapV8
and was made redundant by the JDK upgrade. Please use
rx-client-java8
instead.
Spring version used in the extension module was upgraded to 4.2.1.RELEASE. The reason for that is lack of Java 8 support with Spring 3.x versions. Optionally, an extension module for Spring 5 can be used.
Jersey proprietary reactive client API has been dropped and replaced by JAX-RS 2.1 Reactive Client API. The backwards compatibility rule couldn't be respected in this case, since the JAX-RS API are based on what was done in Jersey and there were unresolvable code incompatibilities.
Following breaking changes are caused by removing and replacing HK2 (ServiceLocator
) by
InjectionManager. Jersey injection API is considered as an internal API (except
InjectionManager
)
Classes in which HK2 ServiceLocator
was simply replaced by
InjectionManager and the replacing influenced their public methods:
MethodHandler |
ComponentProvider |
ExternalRequestScope |
WadlGeneratorConfig |
RequestScopedInitializer |
Support for HK2 Binder
in the case of using HK2 Injection Module was implemented
but Jersey newly supports a registration its own AbstractBinder and
Binder in Application to easily switch from HK2 classes
to Jersey ones just by adjusting the imports.
InjectionManager
contains a mechanism for registering DI specific
injection bindings, in case the application uses CDI, developers should use CDI mechanism, in case the
application uses HK2, developers should configure HK2 - ideally via configuring a parent locator that
is then passed to Jersey. The custom bindings can be also registered through Application
if InjectionManager
supports the bindings type that means that
InjectionManager#isRegistrable
returns true
;
In ResourceConfig and ClientConfig configuration methods for
auto-discoverable components and meta-components (e.g. Feature
) accept
InjectionManager
and moreover the meta-components accept
ManagedObjectFinalizer
which ensures a pre-destroy method invocation on registered
components.
Method getTemplateObjectFactory
in
AbstractTemplateProcessor accepts a function that initializes a retrieved
template factory from a configuration, usually this function is just a wrapper with underlying
InjectionManager
invocation.
HK2 Factory
support is replaced by java.util.function.Supplier
and Jersey-specific DisposableSupplier.
HK2-specific annotations @Optional
, @Immediate
,
@Unqualified
are no longer supported directly in Jersey but can be used if HK2
Injection Module is used.
HK2-specific annotations @PerLookup
and @PerThread
are migrated
to Jersey with an adjusted package.
<dependency> <groupId>org.glassfish.jersey.inject</groupId> <artifactId>jersey-hk2</artifactId> <version>2.45</version> </dependency>
HK2 Binder
being able to be registered as in pre 2.26 Jersey has
been returned back in Jersey 2.29. Note, however, this is for backward compatibility purposes and
not a preferred way of registering injectables; the HK2 Binder
support may be removed
in the future versions of Jersey.
Following, already deprecated, APIs were removed:
LoggingFilter
has been removed. Use LoggingFeature instead. See
Logging chapter.
From version 2.23 onwards, LoggingFilter
has been replaced
with LoggingFeature.
Following APIs were deprecated:
LoggingFilter
has been marked as deprecated and will be removed in a subsequent
release. Use LoggingFeature instead. See chapter
logging.
Last version contained a change in relative URI resolution in the location header. Even though the change was fixing the discrepancy between the real behaviour and RFC7231, it also caused JAX-RS spec incompatibility in some cases. Furthermore, there was no way to preserve backwards compatibility.
Therefore, the default behaviour was rollbacked and a new configuration property was introduced to switch to the RFC7231 compliant behaviour: ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231. Also, the possibility to switch the URI resolution completely off remains with the ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_DISABLED disabled switch. Both properties are false by default.
Last version contained a change in relative URI resolution in the location header. Even though the change was fixing the discrepancy between the real behaviour and RFC7231, it also caused JAX-RS spec incompatibility in some cases. Furthermore, there was no way to preserve backwards compatibility.
Therefore, the default behaviour was rollbacked and a new configuration property was introduced to switch to the RFC7231 compliant behaviour: ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231. Also, the possibility to switch the URI resolution completely off remains with the ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_DISABLED disabled switch. Both properties are false by default.
In previous Jersey versions, if the resource method created a response containing relative URI in the
Location
http header, the URI was resolved against
base uri
of the application. This behaviour was not correct, as pointed out by JERSEY-2838. With this
change, the URI is, by default, resolved against request base uri.
For example, having a resource at http://server.com/api/management/user
, that
returns response with Location: foo
, while the root of the app is
http://server.com/api
, the resulting URI will be:
with Jersey 2.21 and earlier:
http://server.com/api/foo
|
with Jersey 2.22:
http://server.com/api/management/foo
|
Please note, that the trailing slash is significant, so that if the URI ends with a slash (
http://server.com/api/management/user/
), the output will be:
with Jersey 2.21 and earlier:
http://server.com/api/foo
|
with Jersey 2.22:
http://server.com/api/management/user/foo
|
Alternatively, the entire URI resolving logic can be switched off by newly
introduced ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_DISABLED property.
If the value is true
, Jersey will not change the URI contained in the
Location
header at all (even if this behaviour may not match with behaviour described in JavaDoc).
New parameter, org.glassfish.hk2.api.ServiceLocator
, has been added
to ExternalRequestScope methods. This is to allow 3rd party component providers to
hook up with the actual HK2 locator in case of multiple Jersey applications are running in parallel
within a single 3rd party component container. The change was driven by CDI/Servlet requirements.
New method, close
, has been added to ResourceFinder. Its intention
is to release allocated/opened resources (such as streams) without a need to iterate through the
whole ResourceFinder
.
Jersey has updated version of MOXy (XML/JSON provider) to version 2.6. Among some bug fixes there are other notable changes (some of them breaking) that you should be aware of:
Redesign of type
property in JSON processing
- Special handling of JSON
type
property is deprecated. If there is need to identify type of JSON object - due to missing root
element or some special inheritance requirements, it is necessary to specify fully qualified type
property with
http://www.w3.org/2001/XMLSchema-instance
namespace.
Several experimental Jersey APIs have matured enough and as such we have decided to promote them from Beta status, namely:
Jersey Reactive Client API. Also Reactive Client moved from incubator to extension (umbrella) module.
Jersey client-side ClientLifecycleListener SPI.
Jersey server-side ContainerLifecycleListener SPI.
Jersey server-side (MVC) @ErrorTemplate annotation.
Jersey test framework (client-side) LoopBackConnectorProvider connector.
Jersey test framework (server-side) ContainerRequestBuilder class.
These APIs are now part of the official public Jersey 2.x API.
Following, already deprecated, APIs were removed:
org.glassfish.jersey.apache.connector.ApacheClientProperties
- constant
SSL_CONFIG
has been removed. Use ClientBuilder methods to configure SSL in a Client
instance.
org.glassfish.jersey.jetty.connector.JettyClientProperties
- constant
SSL_CONFIG
has been removed. Use ClientBuilder methods to configure SSL in a Client
instance.
FreemarkerMvcFeature.TEMPLATES_BASE_PATH
- constant has been unified across MVC modules and the deprecated one has been removed. Use
FreemarkerMvcFeature.TEMPLATE_BASE_PATH
or property
jersey.config.server.mvc.templateBasePath.freemarker
instead.
JspMvcFeature.TEMPLATES_BASE_PATH
- constant has been unified across MVC modules and the deprecated one has been removed. Use
JspMvcFeature.TEMPLATE_BASE_PATH
or property
jersey.config.server.mvc.templateBasePath.jsp
instead.
Integration of executor providers for Jersey runtime has been unified and refactored. As a result, the
org.glassfish.jersey.spi.RequestExecutorProvider
and
org.glassfish.jersey.spi.RuntimeThreadProvider
SPIs have been removed from Jersey. A new, common & generic executor service providers have been
introduced instead: ExecutorServiceProvider
and ScheduledExecutorServiceProvider. These new providers are used to support
custom qualified executor service injection, including the refactored use cases of client asynchronous
request execution, server-side managed asynchronous request processing as well as server-side
background task scheduler.
From version 2.17 onwards, it's possible to use CDI with JAX-RS web-applications packaged in EAR. All
supported HK2/CDI injections now work as expected for JAX-RS application deployed in the mentioned fashion.
One need to make sure that modules
jersey-cdi1x
and
jersey-cdi1x-servlet
are present in Servlet container (that supports EARs).
From version 2.16 onwards, all JAX-B providers are being bundled in a separate module.
We improved the performance for using sub-resource locators in a Jersey application. The performance gains
are available for cases when the sub-resource locator method returns either a resource class (return value is
e.g.
Class<?>
orClass<MySubResource>
) or a (non-proxied) resource instance (when return value is an
instance of
MySubResource
class).
Jetty connector and Apache connector have been previously using their own custom properties to set SSL context on a connector. These properties have been deprecated and the code has been updated to read the SSL context information from the JAX-RS client configuration. This means that all Jersey connectors now properly accept SSL configuration as configured via standard JAX-RS ClientBuilder methods.
Previously, all Jersey connectors have been using their own default chunk size when HTTP chunked coding was used. Since Jersey 2.16, there is a new default chunk size value used by all connectors, if a custom chunk size is not set. The new default value is stored under ClientProperties.DEFAULT_CHUNK_SIZE client property.
Following APIs were deprecated:
org.glassfish.jersey.apache.connector.ApacheClientProperties
- constant
SSL_CONFIG
has been marked as deprecated and will be removed in a subsequent release.
Use ClientBuilder methods to configure SSL in a Client instance.
org.glassfish.jersey.jetty.connector.JettyClientProperties
- constant
SSL_CONFIG
has been marked as deprecated and will be removed in a subsequent release.
Use ClientBuilder methods to configure SSL in a Client instance.
JAX-B support modularization might cause breaking changes for those users relying on JAX-B and directly referring to the Jersey core-common module:
<dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-common</artifactId> <version>${pre-2.16-version}</version> </dependency>
The following needs to be included in addition from version 2.16 on:
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-jaxb</artifactId> <version>2.45</version> </dependency>
MediaType
's quality source parameters (qs
) reuse the same
parsing as quality parameters. This means that values higher than
1.0
throw ParseException. I.e. following example is not allowed any more:
@Path("/") @Produces("text/html;qs=5") // wrong 'qs' value public class Bookstore { ... }
Before 2.15, CDI integration was supported primarily in Java EE containers with built-in CDI support. From version 2.15 onwards, it is possible to leverage CDI integration also outside of Java EE environment. A new example, helloworld-weld, has been introduced to demonstrate the new feature using Grizzly HTTP server. Another example application, cdi-webapp, has been updated so it enables Apache Tomcat Server deployment.
CDI support improvement caused breaking changes for those users directly referring to the following CDI supporting Jersey module in maven:
<dependency> <groupId>org.glassfish.jersey.containers.glassfish</groupId> <artifactId>jersey-gf-cdi</artifactId> <version>${pre-2.15-version}</version> </dependency>
The above dependency needs to be replaced with:
<dependency> <groupId>org.glassfish.jersey.ext.cdi</groupId> <artifactId>jersey-cdi1x</artifactId> <version>2.45</version> </dependency>
The following needs to be included in addition if you want to leverage CDI JTA support:
<dependency> <groupId>org.glassfish.jersey.ext.cdi</groupId> <artifactId>jersey-cdi1x-transaction</artifactId> <version>2.45</version> </dependency>
Following experimental APIs have been promoted to become part of public Jersey API:
Jersey client-side HttpAuthenticationFeature API.
Jersey server-side DestroyListener (formerly
ExtendedMonitoringStatisticsListener
), which has been slightly refactored and is
now a separate interface (e.g. not extendingMonitoringStatisticsListener
), hence
providing better compatibility with lambdas.
These APIs are now part of the official public Jersey 2.x API.
Because of a bug fix for issue
JERSEY-2602, we re-generate WADL
classes from
wadl.xsd
to make sure the getters for boolean properties starts with
is
instead of
get
as in Jersey 1 and Jersey <= 2.6.
For performance purposes a new server property ServerProperties.MONITORING_ENABLED has
been introduced. It is possible to enable just basic almost static monitoring information using the
property. It allows to inject ApplicationInfo object, renamed original
class org.glassfish.jersey.server.monitoring.ApplicationStatistics
.
And MonitoringStatistics no more have a reference to
ApplicationStatistics
, method
getApplicationStatistics()
has been removed.
Several experimental Jersey APIs have matured enough and as such we have decided to promote them from Beta status, namely:
Jersey client-side ConnectorProvider SPI.
Jersey server-side ResponseErrorMapper SPI.
These APIs are now part of the official public Jersey 2.x API.
Jersey is now preventing message body providers (MBR, MBW) from closing given input/output stream. With this change Jersey is enforcing the JavaDoc statements present in message body providers.
We have reintroduced support for JSON processing via Jackson 1.x JSON provider (1.9.11). In order to use
Jackson 1 in your application you need to add
jersey-media-json-jackson1
module (+ its dependencies) to your class-path and register
Jackson1Feature
in your application (server or client).
Client-side providers (such asClientRequestFilter
s) implementing the new
org.glassfish.jersey.client.ClientLifecycleListener
interface will be notified when various lifecycle events occur. Currently client runtime initialization
triggers the
onInit()
method and client closing triggers
onClose()
method. Such providers implementing the
ClientLifecycleListener
can be registered in a common way, e.g. into a
JerseyClient
or
JerseyWebTarget
instance, or into a (potentially) auto discoverable feature context.
Gerard updated the Declarative Linking extension module which has been ported to Jersey 2 in version 2.6. You can read more about what Declarative Linking does and what it's capable of in the following blog posts:
Our media module that supports working with JSON via Jackson library has been updated to use Jackson 2.x
(2.3.2). All samples and tests have been rewritten to use Jackson 2 as well. In order to use Jackson 2 in your
application you need to add jersey-media-json-jackson (+ its Jackson dependencies) to your class-path and
register
JacksonFeature
in your application.
We dropped automatic registration of message body providers (MessageBodyWriter, MessageBodyReader) and
exception mappers via META-INF/services mechanism. This functionality can be restored by adding
jersey-metainf-services
module to the class-path of your application.
Note: This change may affect 3rd party libraries (e.g. Jackson 2.x) in a way their provider would not be
registered in an JAX-RS app. You need to either register them manually or use mentioned
jersey-metainf-services
module.
Jersey Test Framework now supports TestNG to run the tests (in addition to the JUnit, which is supported by default). You can now run the tests in parallel using either JUnit or TestNG. See chapters dedicated to TestNG and parallel testing for more information: Section 29.3, “Running TestNG Tests” and Section 29.5, “Parallel Testing with Jersey Test Framework”.
Some of the feature specific configuration properties (disable WADL, disable BV, disable
JSON-Processing, enable Monitoring), and their server/client counterparts, are no longer affected by a
value of properties
CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE
or
CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE
. The specific properties have to
be used to change default behaviour of mentioned features (e.g.
ServerProperties.WADL_FEATURE_DISABLE
).
Automatic registration of MessageBodyWriter
,
MessageBodyReaders
and
ExceptionMappers
via
META-INF/services
mechanism has been removed. Disabling the automatic registration of providers via
META-INF/services
may affect 3rd party libraries (i.e. Jackson 2.x) that are using this mechanism to register its
providers. In order to restore this functionality the
org.glassfish.jersey.ext:jersey-metainf-services
has to be added on the classpath. Otherwise such providers has to be registered manually.
The Jackson JSON Jersey module has been updated to use Jackson 2.x instead of Jackson 1.x. This means that all the code that has been using Jackson 1.x for JSON (de)serialization has to be migrated to Jackson 2.x.
Because of a bug fix for issue
JERSEY-2458, there has been a
slight change in the behavior of UriInfo
getPath
and
getPathSegments
methods. The
getPath
methods no longer return a path prefixed with a slash ('/'
), instead they now
correctly return a request path
relative
to the base request URI. Also, the UriInfo
now correctly handles requests which URI
contains empty path segments (e.g.http://localhost///a/b//c
). These empty path
segments are now correctly included in the lists returned by the
UriInfo.getPathSegments
methods.
SseFeature now gets automatically discovered and enabled if the SSE module is present on
the class path. This behavior can be suppressed by setting DISABLE_SSE
property to true
. The behavior can also be selectively suppressed in either client
or server runtime by setting the DISABLE_SSE_CLIENT
or DISABLE_SSE_SERVER property respectively.
Deprecated
getDestroyTime
method has been removed from
org.glassfish.jersey.server.monitoring.ApplicationStatistics
. To get the
application shutdown information, a ContainerLifecycleListener should be registered
and its
onShutdown
method implemented to listen to and process the application shutdown event.
Method
triggerEvent(RequestEvent.Type)
has been removed from the public ContainerRequest API. This method has never been
intended for public, application-level use.
In Jersey 2.7 and earlier it was (under certain conditions) possible to supply
custom TestContainerFactory as part of the tested JAX-RS / Jersey application. This
factory would be picked and used by JerseyTest to
instantiate TestContainer that will host the tested application. This feature was
unreliable and redundant. As such, support for the feature has been removed. To specify a
custom TestContainerFactory
to be used by your JerseyTest
subclass, please override the
JerseyTest.getTestContainerFactory
method instead. Overriding
getTestContainerFactory
now remains the only reliable way of specifying custom TestContainerFactory
implementation to be used in your tests.
Protected method
setTestContainerFactory
has been removed from the JerseyTest
API as calling the method had no effect on
the TestContainerFactory
instance used by the JerseyTest
subclass.
Protected method
getClient
has been removed from the JerseyTest
API. To configure test client instances, please
override the
configureClient
method instead.
Utility methods JerseyTest
that provide access to
pre-configured Client and WebTarget instances (
client()
,
target(...)
) have been made final to prevent overriding in subclasses and thus
ensure consistency of the jersey test framework functionality.
JerseyTest
constructor
JerseyTest(Class<? extends Application>)
has been made deprecated and will be removed in the subsequent Jersey release.
It was previously possible to pass in a custom ContainerProvider that was supposed to deploy and run the application as one of the JAX-RS / Jersey application providers. This ability has been removed without any substitute as the concept was fundamentally flawed. Typical use cases should not be affected by this change.
Factory methods
createHttpServer
which take Jersey ApplicationHandler as one of the input parameters have been removed
from the Jersey container factory API as inherently broken. This
impacts GrizzlyHttpServerFactory, JdkHttpServerFactory, JettyHttpContainerFactory
and SimpleContainerFactory implementations. The methods that
take ResourceConfig as input parameter should be used instead. Typical use cases
should not be affected by this change.
Method
registerAdditionalBinders
on ApplicationHandler has been removed from the public API. Please use the
specific ApplicationHandler
constructor that accepts custom HK2 binders instead.
Several configuration properties were renamed, especially those having client and server versions
along with the common version in CommonProperties
. Please see following table for
complete reference:
Table 31.1. List of changed configuration properties:
Constant | Old value (Jersey 2.7 and before) | New value (Jersey 2.8+) |
---|---|---|
ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE |
jersey.config.disableAutoDiscovery.client
|
jersey.config.client.disableAutoDiscovery
|
ServerProperties.FEATURE_AUTO_DISCOVERY_DISABLE |
jersey.config.disableAutoDiscovery.server
|
jersey.config.server.disableAutoDiscovery
|
ClientProperties.JSON_PROCESSING_FEATURE_DISABLE |
jersey.config.disableJsonProcessing.client
|
jersey.config.client.disableJsonProcessing
|
ServerProperties.JSON_PROCESSING_FEATURE_DISABLE |
jersey.config.disableJsonProcessing.server
|
jersey.config.server.disableJsonProcessing
|
ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE |
jersey.config.disableMetainfServicesLookup.client
|
jersey.config.client.disableMetainfServicesLookup
|
ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE |
jersey.config.disableMetainfServicesLookup.server
|
jersey.config.server.disableMetainfServicesLookup
|
ClientProperties.MOXY_JSON_FEATURE_DISABLE |
jersey.config.disableMoxyJson.client
|
jersey.config.client.disableMoxyJson
|
ServerProperties.MOXY_JSON_FEATURE_DISABLE |
jersey.config.disableMoxyJson.server
|
jersey.config.server.disableMoxyJson
|
ClientProperties.OUTBOUND_CONTENT_LENGTH_BUFFER |
jersey.config.contentLength.buffer.client
|
jersey.config.client.contentLength.buffer
|
ServerProperties.OUTBOUND_CONTENT_LENGTH_BUFFER |
jersey.config.contentLength.buffer.server
|
jersey.config.server.contentLength.buffer
|
ServerProperties.TRACING |
jersey.config.server.tracing
|
jersey.config.server.tracing.type
|
The old names are still working for now, but are deprecated. There is a fallback mechanism implemented
while reading the property and each get, that resolves the value from the old-named property, will log
a
CONFIG
level warning.
Until version 2.6, Jersey was compiled with Java SE 6. This has changes in Jersey 2.7. Now almost all
Jersey components are compiled with Java SE 7 target. It means, that you will need at least Java SE 7
to be able to compile and run your application that is using latest Jersey. Only
core-common
and
core-client
modules are still compiled with Java class version runnable with Java SE 6.
MVC support: method
writeTo
of TemplateProcessor was modified by adding an argument MultivaluedMap<String,
Object> httpHeaders
. This is an incompatible change (the method was modified directly in
the interface). All Jersey provided MVC implementation were adjusted but if you have your own MVC
implementation then you need to modify the method signature of the implementation.
A minor JAX-RS incompatibility issue has been recently discovered and reported (see JERSEY-2387). As part of the fix,
minor breaking changes related to URI resolving and creation have been introduced in the behavior
of UriBuilder, Link.Builder and WebTarget classes. It is no
longer possible to successfully build a new URI
instance from a UriBuilder
that contains unresolved template parameters. An
IllegalArgumentException
will be thrown in such case, as mandated by JAX-RS API javadoc. Similarly, it is not possible to
successfully create a Link instance from a URI template with unresolved template
parameters. Also, it is not possible to successfully send a request on a WebTarget
that represents a URI template that does not have all the template parameters properly resolved. Any
attempt to do so will fail with an exception. Note that this also applies to any managed clients
injected into JAX-RS server-side components using Uri annotation.
In Jersey 2.6 and earlier, producing a URI from an incompletely resolved URI template would succeed
and all unresolved template parameter locations would be encoded without change into the resulting
URI, for example
"/path/{param}"
would be implicitly encoded as
"/path/%7Bparam%7D"
. While we do not expect our users to depend on this
functionality, if the former behavior is desired for some reason,
UriComponent.encodeTemplateNames
method can be used instead:
URI.create(UriComponent.encodeTemplateNames(UriBuilder.fromUri("/path/{param}").toTemplate()));
or simply
URI.create(UriComponent.encodeTemplateNames("/path/{param}"));
Jersey no longer depend directly on Guava and ASM artifacts which means that users are free to use their own versions of mentioned libraries.
New bundle has been created for Guava (bundles/repackaged/jersey-guava
), with Maven
coordinates:
org.glassfish.jersey.bundles.repackaged:jersey-guava
(Repackaged) ASM is now part of Jersey Server. Jersey currently uses ASM 5 for package-scanning capabilities.
Following APIs were deprecated:
org.glassfish.jersey.message.internal.HttpDateFormat
- method
getPreferedDateFormat()
has been marked as deprecated due to typo in the name. New method
getPreferredDateFormat()
should be used instead.
Following, already deprecated, APIs were removed:
org.glassfish.jersey.client.filter.HttpBasicAuthFilter
and
org.glassfish.jersey.client.filter.HttpDigestAuthFilter
(use HttpAuthenticationFeature instead)
org.glassfish.jersey.apache.connector.ApacheClientProperties.HTTP_PARAMS
(use
org.glassfish.jersey.apache.connector.ApacheClientProperties#REQUEST_CONFIG
instead),
org.glassfish.jersey.apache.connector.ApacheClientProperties.PROXY_URI
,
org.glassfish.jersey.apache.connector.ApacheClientProperties.PROXY_USERNAME
,
org.glassfish.jersey.apache.connector.ApacheClientProperties.PROXY_PASSWORD
(use corresponding ClientProperties instead.
org.glassfish.jersey.server.validation.ValidationConfig.setMessageInterpolator
org.glassfish.jersey.server.validation.ValidationConfig.setTraversableResolver
org.glassfish.jersey.server.validation.ValidationConfig.setConstraintValidatorFactory
org.glassfish.jersey.server.validation.ValidationConfig.setParameterNameProvider
(use corresponding methods of the same class without
"set"
prefix in the method names).
org.glassfish.jersey.server.mvc.MvcProperties
(use properties of
org.glassfish.jersey.server.mvc.MvcFeature
instead).
MVC does not allow to specify the resolving class. Resolving class is used to create a path of the template. Changes are:
Annotation attribute
Class<?> org.glassfish.jersey.server.mvc.Template.resolvingClass()
(the attribute was obsolete and therefore removed. Resolving class now always the resource class in
which the MVC resource method is defined).
resolvingClass
was removed from Viewable. The constructor no longer accepts this argument and
there is no getter for this field.
org.glassfish.jersey.server.mvc.freemarker.FreemarkerProperties
(use FreemarkerMvcFeature instead)
org.glassfish.jersey.server.mvc.jsp.JspProperties
(use JspMvcFeature instead)
org.glassfish.jersey.server.model.RuntimeResource.getFirstParentResource()
(use Resource.getParent() instead).
WADL is by default displayed in the simplified form. It does not contain supporting resources like OPTIONS
methods or
/application.wadl
itself. In order to get the full WADL use query param detail=true
. For example make a
GET request to http://localhost:8080/application.wadl?detail=true
.
WADL is by default displayed in the simplified form. It does not contain supporting resources like OPTIONS
methods or
/application.wadl
itself. In order to get the full WADL use query paramdetail=true
. For example make a
GET request to http://localhost:8080/application.wadl?detail=true
.
Client chunked encoding configuration behaviour has changed:
Jersey client uses chunked encoding (streaming) for serialization of the entity as a default option.
Before Jersey 2.5 release entity buffering has been used by default. The size of the chunk can still
be controlled by ClientProperties.CHUNKED_ENCODING_SIZE property, this property
however no longer enforces the use of chunked encoding. To control request entity buffering and
chunked transfer coding selection, please utilize use the new
ClientProperties.REQUEST_ENTITY_PROCESSING property. The behaviour of the property
is however not unified across the available Connector implementations and depends
on the connector implementation configured for the Client instance.
Default connector produced by HttpUrlConnectorProvider still uses
buffering as default options due to bugs in HttpURLConnection
. On the other hand,
Jetty HTTP Client based connectors produced by JettyConnectorProvider do not support
chunked encoding at all.
Please note that this is not a newly introduced limitation - it's merely an official acknowledgement of the fact that different connectors have different capabilities and limitations - something that has always been part of the individual connector implementations, it just was not publicly acknowledged.
New ConnectorProvider SPI has been introduced to decouple Connector
instantiation from Client instance boot-strapping. As such, the
connector(Connector)
method has been removed from ClientConfig
API. It has been replaced with a newly introduced
connectorProvider(ConnectorProvider)
method.
org.glassfish.jersey.client.HttpUrlConnector
has been removed from the public API.
HttpUrlConnectorProvider should be used to produce HttpURLConnection
connector instances instead.
ClientProperties.HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND
property has been moved to the new HttpUrlConnectorProvider
has been introduced in Jersey 2.4) has been moved to the new HttpUrlConnectorProvider
class as this property is specific to the connector instances created by
HttpUrlConnectorProvider
only. The property has been also renamed to
HttpUrlConnector.SET_METHOD_WORKAROUND. The name of the property
remains the same - jersey.config.client.httpUrlConnection.setMethodWorkaround
.
ClientProperties.HTTP_URL_CONNECTOR_FIX_LENGTH_STREAMING
property (that
class as this property is specific to the connector instances created by
HttpUrlConnectorProvider
only. The property has been also renamed to
HttpUrlConnectorProvider.USE_FIXED_LENGTH_STREAMING and the new property name
is jersey.config.client.httpUrlConnector.useFixedLengthStreaming
.
org.glassfish.jersey.grizzly.connector.GrizzlyConnector
has been removed from the public
API. GrizzlyConnectorProvider should be used to produce Grizzly Asynchronous HTTP Client
connector instances instead.
Public constructor has been removed from the org.glassfish.jersey.apache.connector.ApacheConnector
; API.
ApacheConnectorProvider should be used to provide Apache HTTP Client
connector instances instead.
Public constructor has been removed from the org.glassfish.jersey.jetty.connector.JettyConnector
; API.
JettyConnectorProvider should be used to provide Jetty HTTP Client
connector instances instead.
Renamed property CACHING_TEMPLATES_ENABLED
in MustacheMvcFeature
from jersey.config.server.mvc.caching.mustache.enabled
to
jersey.config.server.mvc.caching.mustache
.
Authentication filters org.glassfish.jersey.client.filter.HttpBasicAuthFilter
and org.glassfish.jersey.client.filter.HttpDigestAuthFilter
were deprecated and replaced by HttpAuthenticationFeature.
The ContainerLifecycleListener invokes event
onStartup
and
onShutdown
also when application is being started or stopped because of application redeploy. The interface was
marked as a Beta now.
The monitoring statistics method
ApplicationStatistics.getDestroyTime()
is deprecated and returns always null. Use ContainerLifecycleListener to listen on
application destroy and get the destroy time.
org.glassfish.jersey.spi.ResponseExecutorsProvider
contract has been completely removed from the Jersey SPI as it was inconsistently used by Jersey
runtime and we did not find a suitable use case where a custom response executor would make sense.
While we have no indication that the removed SPI is used in the Jersey community, please do not
hesitate to contact us in case you think that you have a valid use case where the use of a custom
response executor makes sense.
org.glassfish.jersey.spi.RequestsExecutorsProvider
contract has been renamed to
org.glassfish.jersey.spi.RequestsExecutorsProvider
. It has been also extended with
an additional
releaseRequestingExecutor
method to address executor shutdown handling issues reported in JERSEY-2205. As such, any custom
implementation of the SPI is now required to implement the new method. (Note that the SPI has been
removed in Jersey 2.18 - see the Jersey 2.18 release migration guide section for more details.)
The unsupported
ClientProperties.BUFFER_RESPONSE_ENTITY_ON_EXCEPTION
property, with value of jersey.config.client.bufferResponseEntityOnException
, has been
removed from the API. Since Jersey 2.4 where
JERSEY-2157
issue has been fixed, Jersey client runtime automatically buffers error response entities. This behavior
is automatic and there is no need to set any property.
All deprecated SSE InboundEvent
getData(...)
methods have been removed from the API. Use the new
readData(...)
methods have been introduced instead in Jersey 2.3 for consistency with other parts of client-side JAX-RS
API. Access to the raw SSE event data content is provided via a InboundEvent
's
byte[] getRawData()
method that has been introduced in Jersey 2.3 as well.
All EJB and CDI integration classes have been moved into internal Jersey packages, to clearly state the integration code should not be used as a public API.
All existing SSE InboundEvent
getData(...)
methods have been made deprecated and new
readData(...)
methods have been introduced instead for consistency with other parts of client-side JAX-RS API. The
deprecated
getData(...)
methods will be removed in Jersey 2.4. A new SSE InboundEvent
byte[] getRawData()
method has been introduced to provide access to the raw SSE event data content.
Generic Broadcaster methods for adding/removing BroadcasterListener
registrations have been renamed from
addBroadcasterListener/removeBroadcasterListener
to simply add/remove
.
Generic Broadcaster (and transitively, SseBroadcaster)
add/remove
methods - that are responsible for adding/removing BroadcasterListener
and ChunkedOutput (or EventOutput) registrations - no longer try to avoid
duplicate registrations by comparing hash code of the added/removed instance with the hash codes of
already registered instances. This behavior has been identified as a potential source of hard to discover
bugs and was removed as such. The issue with the former behavior was that hash codes as integer values
provide only a very limited value space that could lead to false-positive duplicate registration
rejections, especially with larger number of simultaneously connected SSE clients (represented
by ChunkedOutput
or EventOutput
broadcaster registrations).
Consequently, users who rely on the old registration behavior in their application code need to adapt the
code to the revised behavior of Broadcaster
add/remove
methods.
This chapter is a migration guide for people switching from Jersey 1.x. Since many of the Jersey 1.x features became part of JAX-RS 2.0 standard which caused changes in the package names, we decided it is a good time to do a more significant incompatible refactoring, which will allow us to introduce some more interesting new features in the future. As the result, there are many incompatibilities between Jersey 1.x and Jersey 2.0. This chapter summarizes how to migrate the concepts found in Jersey 1.x to Jersey/JAX-RS 2.0 concepts.
Jersey 1.x contains number of proprietary server APIs. This section covers migration of application code relying on those APIs.
Jersey 1.x have its own internal dependency injection framework which handles injecting various parameters into field or methods. It also provides a way how to register custom injection provider in Singleton or PerRequest scopes. Jersey 2.x uses HK2 as dependency injection framework and users are also able to register custom classes or instances to be injected in various scopes.
Main difference in Jersey 2.x is that you don't need to create special classes or providers for this task; everything should be achievable using HK2 API. Custom injectables can be registered at ResourceConfig level by adding new HK2 Module or by dynamically adding binding almost anywhere using injected HK2 Services instance.
Jersey 1.x Singleton:
ResourceConfig resourceConfig = new DefaultResourceConfig(); resourceConfig.getSingletons().add( new SingletonTypeInjectableProvider<Context, SingletonType>( SingletonType.class, new SingletonType()) {});
Jersey 1.x PerRequest:
ResourceConfig resourceConfig = new DefaultResourceConfig(); resourceConfig.getSingletons().add( new PerRequestTypeInjectableProvider<Context, PerRequestType>() { @Override public Injectable<PerRequestType> getInjectable(ComponentContext ic, Context context) { //... } });
Jersey 2.0 HK2 Module:
public static class MyBinder extends AbstractBinder { @Override protected void configure() { // request scope binding bind(MyInjectablePerRequest.class).to(MyInjectablePerRequest.class).in(RequestScoped.class); // singleton binding bind(MyInjectableSingleton.class).in(Singleton.class); // singleton instance binding bind(new MyInjectableSingleton()).to(MyInjectableSingleton.class); } } // register module to ResourceConfig (can be done also in constructor) ResourceConfig rc = new ResourceConfig(); rc.addClasses(/* ... */); rc.addBinders(new MyBinder());
Jersey 2.0 dynamic binding:
public static class MyApplication extends Application { @Inject public MyApplication(ServiceLocator serviceLocator) { System.out.println("Registering injectables..."); DynamicConfiguration dc = Injections.getConfiguration(serviceLocator); // request scope binding Injections.addBinding( Injections.newBinder(MyInjectablePerRequest.class).to(MyInjectablePerRequest.class).in(RequestScoped.class), dc); // singleton binding Injections.addBinding( Injections.newBinder(MyInjectableSingleton.class) .to(MyInjectableSingleton.class) .in(Singleton.class), dc); // singleton instance binding Injections.addBinding( Injections.newBinder(new MyInjectableSingleton()) .to(MyInjectableSingleton.class), dc); // request scope binding with specified custom annotation Injections.addBinding( Injections.newBinder(MyInjectablePerRequest.class) .to(MyInjectablePerRequest.class) .qualifiedBy(new MyAnnotationImpl()) .in(RequestScoped.class), dc); // commits changes dc.commit(); } @Override public Set<Class<?>> getClasses() { return ... }}
In Jersey 1, the reload functionality is based on two interfaces:
Containers, which support the reload functionality implement the
ContainerListener
interface, so that once you get access to the actual container instance, you could call its
onReload
method and get the container re-load the config. The second interface helps you to obtain the actual container
instance reference. An example on how things are wired together follows.
Example 31.1. Jersey 1 reloader implementation
public class Reloader implements ContainerNotifier { List<ContainerListener> ls; public Reloader() { ls = new ArrayList<ContainerListener>(); } public void addListener(ContainerListener l) { ls.add(l); } public void reload() { for (ContainerListener l : ls) { l.onReload(); } } }
Example 31.2. Jersey 1 reloader registration
Reloader reloader = new Reloader(); resourceConfig.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_NOTIFIER, reloader);
In Jersey 2, two interfaces are involved again, but these have been re-designed.
The
Container
interface introduces two
reload
methods, which you can call to get the application re-loaded. One of these methods allows to pass in a
new ResourceConfig
instance.
You can register your implementation of
ContainerLifecycleListener
the same way as any other provider (i.e. either by annotating it by @Provider annotation or adding
it to the Jersey ResourceConfig directly either using the class (using
ResourceConfig.addClasses()
) or registering a particular instance using
ResourceConfig.addSingletons()
method.
An example on how things work in Jersey 2 follows.
Example 31.3. Jersey 2 reloader implementation
public class Reloader implements ContainerLifecycleListener { Container container; public void reload(ResourceConfig newConfig) { container.reload(newConfig); } public void reload() { container.reload(); } @Override public void onStartup(Container container) { this.container = container; } @Override public void onReload(Container container) { // ignore or do whatever you want after reload has been done } @Override public void onShutdown(Container container) { // ignore or do something after the container has been shutdown } }
Example 31.4. Jersey 2 reloader registration
Reloader reloader = new Reloader(); resourceConfig.addSingletons(reloader);
JAX-RS 2.0 defines new order of MessageBodyWorkers - whole set is sorted by declaration distance, media type
and source (custom providers having higher priority than default ones provided by Jersey). JAX-RS 1.x ordering
can still be forced by setting parameter
MessageProperties.LEGACY_WORKERS_ORDERING
("jersey.config.workers.legacyOrdering"
) to true
in ResourceConfig
or ClientConfig
properties.
JAX-RS 2.0 provides functionality that is equivalent to the Jersey 1.x proprietary client API. Here is a rough mapping between the Jersey 1.x and JAX-RS 2.0 Client API classes:
Table 31.2. Mapping of Jersey 1.x to JAX-RS 2.0 client classes
Jersey 1.x Class | JAX-RS 2.0 Class | Notes |
---|---|---|
com.sun.jersey.api.client.Client | ClientBuilder | For the static factory methods and constructors. |
Client | For the instance methods. | |
com.sun.jersey.api.client.WebResource | WebTarget | |
com.sun.jersey.api.client.AsyncWebResource | WebTarget | You can access async versions of the async methods by calling
WebTarget.request().async()
|
The following sub-sections show code examples.
Jersey 1.x way:
Client client = Client.create(); WebResource webResource = client.resource(restURL).path("myresource/{param}"); String result = webResource.pathParam("param", "value").get(String.class);
JAX-RS 2.0 way:
Client client = ClientBuilder.newClient(); WebTarget target = client.target(restURL).path("myresource/{param}"); String result = target.pathParam("param", "value").get(String.class);
Jersey 1.x way:
Client client = Client.create(); WebResource webResource = client.resource(restURL); webResource.addFilter(new HTTPBasicAuthFilter(username, password));
JAX-RS 2.0 way:
Client client = ClientBuilder.newClient(); WebTarget target = client.target(restURL); target.register(new HttpBasicAuthFilter(username, password));
Jersey 1.x way:
Client client = Client.create(); WebResource webResource = client.resource(restURL).accept("text/plain"); ClientResponse response = webResource.get(ClientResponse.class);
JAX-RS 2.0 way:
Client client = ClientBuilder.newClient(); WebTarget target = client.target(restURL); Response response = target.request("text/plain").get();
Jersey 1.x way:
Client client = Client.create(); WebResource webResource = client.resource(restURL); ClientResponse response = webResource.post(ClientResponse.class, "payload");
JAX-RS 2.0 way:
Client client = ClientBuilder.newClient(); WebTarget target = client.target(restURL); Response response = target.request().post(Entity.text("payload"));
Jersey 1.x way:
HTTPSProperties prop = new HTTPSProperties(hostnameVerifier, sslContext); DefaultClientConfig dcc = new DefaultClientConfig(); dcc.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, prop); Client client = Client.create(dcc);
Jersey 2.0 way:
Client client = ClientBuilder.newBuilder() .sslContext(sslContext) .hostnameVerifier(hostnameVerifier) .build();
JSON Support has undergone certain changes in Jersey 2.x. The most visible difference for the developer is in the initialization and configuration.
In Jersey 1.x, the JAXB/JSON Support was implemented as a set of
MessageBodyReaders
and
MessageWriters
in the
jersey-json
module. Internally, there were several implementations of JSON to Object mapping ranging from Jersey's own custom
solution to third party providers, such as
Jackson
orJettison
. The configuration of the JSON support was centralized in the
JSONConfiguration
and
JSONJAXBContext
classes.
There are three main JSON-mapping handling approaches, which are preserved in Jersey 2: JAXB-based, POJO mapping and Low-level parsing The following table shows how to enable each of them in both Jersey 2 compared to Jersey 1:
Table 31.3. JSON approaches and usage in Jersey 1 vs Jersey 2
Approach | Jersey 1 | Jersey 2 |
---|---|---|
POJO | registerPOJOMappingFeature , use ObjectMapper for
configuration
|
use
Jackson
provider: (add
jersey-media-json-jackson
dependency and
register
theJacksonFeature ), configure with custom ObjectMapper
instance.
|
JAXB | Default; useJSONConfiguration /
JSONJAXBContext
for configuration
| use
MOXy
(add the
jersey-media-moxy
dependency; the feature will be registered
automatically), configure using
MoxyJsonConfig
|
Low-level | Direct usage of
JSONObject
and/or
JSONArray
classes
| use JSON-P (standard) or Jettison (non-standard) APIs (add the relevant dependency) |
Example 31.5. Initializing JAXB-based support with MOXy
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-moxy</artifactId> <version>2.45</version> </dependency>
For JAXB-based support, MOXy is the default way in Jersey 2. However, other providers (
Jackson
,Jettison
) can be used as well. The relevant feature has to be
registered (and dependency added) and custom implementation of
ContextResolver
has to be provided. See the code snippets in the related chapter.
For more on particular
Feature
registration, see also:
Jackson registration,
Jettison registration,
MOXy registration,
JSON-P registration.
It is important to point out, that the
Feature
registration has to be done separately for client and server.
With Jersey 2.9,
Jackson
has been updated to version 2.3.2. The feature is still configured via mentioned
ObjectMapper
class, but the package has changed.
jackson 1.x
, use
org.codehaus.jackson.map.ObjectMapper
jackson 2.x
, use
com.fasterxml.jackson.core.ObjectMapper
Jersey 1 was selecting the provider automatically based on the desired JSON Notation. This concept was replaced in Jersey 2 by direct choice of provider (as shown above). To provide some guide how to achieve the same results as in the previous Jersey version, see the following list:
MAPPED
not supported
NATURAL
default MOXy output
JETTISON_MAPPED
supported by Jettison
BADGERFISH
supported by Jettison
As mentioned, the centralized configuration of Jersey 1's
JSONConfiguration
does not have a direct equivalent in Jersey 2. Each provider has its own way to be configured. Detailed
description of each method and property is out of scope of this migration guide and can be found in the
documentation and APIs of the relevant providers and/or the relevant Jersey module API. Bellow are several
basic examples how to configure certain options when using MOXy with Jersey's
MoxyJsonConfig
class.
Formated output
Jersey 1:
JSONConfiguration.createJSONConfigurationWithFormatted()
Jersey 2/MOXy:
MoxyJsonConfig.setFormattedOutput()
Namespaces mapping
Jersey 1:
JSONConfiguration.natural().xml2JsonNs()
Jersey 2/MOXy:
MoxyJsonConfig.setNamespacePrefixMapper()
Namespace separator
Jersey 1:
JSONConfiguration.natural().nsSeparator()
Jersey 2/MOXy:
MoxyJsonConfig.setNamespaceSeparator()
Properties can be also passed directly to
Marshaller
and/or
Unmarshaller
using: MoxyJsonConfig
's property()
,
marshallerProperty()
and
unmarshallerProperty()
methods.
More on the JSON Support topic can be found in Section 9.1, “JSON”.