users@jersey.java.net

[Jersey] Re: Beware of JacksonFeature in Jersey

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Thu, 19 Dec 2013 01:27:11 +0100

On 19 Dec 2013, at 00:58, Robert DiFalco <robert.difalco_at_gmail.com> wrote:

> The ContextResolver will definitely help, but ultimately I would want
> a singleton instance for both the MessageBodyReader and
> MessageBodyWriter (i.e. one JacksonJsonProvider). There really is no
> reason to have one created and injected anew for each and every
> request.

?? JAX-RS providers are singleton (per application) by default. Nothing should get created per request in this case.

> Absolutely, I think the META-INF.services is their issue not yours.
> But it will make it a bummer supporting 2.3.0 in a JacksonFeature and
> prevent those in .services from over-riding those in the feature.
> Worse yet, the service designates JacksonJsonProvider instead of
> JacksonJaxbJsonProvider.
>
> Btw, another CONCRETE suggestion on your existing feature. You should
> also register the Jackson Exception mappers so that parsing and
> generation exceptions are translated into sensible HTTP status codes.
> That bit me since they were not being registered and would just show
> up as 500 errors.

Thanks. Good point. Can you please file a Jira ticket?

Marek

>
> On Wed, Dec 18, 2013 at 12:47 PM, Marek Potociar
> <marek.potociar_at_oracle.com> wrote:
>> As for the conflicts, in Jersey 2.x we support following JSON providers:
>> Java EE JSON Processing, Jackson, Jettison and MOXy (See also
>> https://jersey.java.net/documentation/latest/media.html#json)
>>
>> As for the single object mapper, you can supply a custom ObjectMapper
>> ContextResolver.
>>
>> As for independent Jackson version (b), well, Jackson 2.x, quite naturally,
>> has decided to polish up the packages and APIs which make our module Jackson
>> 1.x incompatible with it. We can and will fix this and update to Jackson 2.x
>> (soonish). You can also give it a try and contribute a patch yourself to
>> expedite the upgrade if you feel so strongly about this - but certainly no
>> pressure :)
>> Alternatively, you can just go "wild" :) and register the Jackson providers
>> on your own. But then you are really on your own. If you run into an issue,
>> unless you provide a self-contained, easily compilable and runnable project
>> with source code that reproduces your issue, we will not be able to help.
>> Why self contained? Because in such case every bit of configuration may
>> matter.
>>
>> Ad (c), I think that the custom context resolver for the object mapper can
>> work. We can also improve the Feature API based on your CONCRETE suggestions
>> (or pull requests).
>>
>> As for the bug - it's not a Jersey bug. It's actually a problem in Jackson.
>> JAX-RS spec mandates us to look for providers by default in
>> META-INF/services. So we do. This is not to be mistaken for package scanning
>> though. If Jackson 2.x has META-INF/services entries and you put in on class
>> path, we will find these (unless you explicitly disable the
>> META-INF/services scanning, of course). See - how quickly one can get into
>> troubles with unmanaged automatic provider discovery... Please ask Jackson
>> leads to consider removing these entries from their jars - or at least
>> produce additional jar artifacts that would not contain these entries.
>>
>> Marek
>>
>> On 18 Dec 2013, at 20:21, Robert DiFalco <robert.difalco_at_gmail.com> wrote:
>>
>> The only problem I see is if you include the MOXy jars, right? The
>> issues I have with your approach is that (a) it does not allow me to
>> use a singleton JacksonJsonProvider that uses a single ObjectMapper
>> for everything, (b) it does not allow me to rev Jackson independent of
>> Jersey version, and (c) it does not allow me to customize settings on
>> the provider for example adding the AfterburnerModule to ObjectMapper.
>>
>> Again, I'm not sure why this isn't pluggable and requires Jersey
>> specific code (such as the MOXy disable feature setting) to add
>> different JSON processors.
>>
>> Also, and maybe I found a bug, but the Service Finder seems to find
>> ANYTHING in the class path that is annotated with @Provider and load
>> it. So even with the JacksonFeature implementation in Jersey, any
>> @Provider annotated classes are still be instantiated in my
>> deployment. The only way I have been able to suppress them was to
>> enable CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE. Which I'm
>> sure is not what is intended. But it's weird having packages outside
>> of what I registered with "packages()" get scanned.
>>
>> On Wed, Dec 18, 2013 at 10:27 AM, Marek Potociar
>> <marek.potociar_at_oracle.com> wrote:
>>
>> Just a warning to all Jersey users:
>> Please be aware that the approach described bellow is not officially
>> supported and may lead you into troubles in the future, esp. wrt. multiple
>> JSON providers getting registered in certain setups, which may potentially
>> errors caused by conflicting, competing JSON entity providers.
>>
>> As for Jackson version, it is true that Jersey now still supports 1.9,
>> anyone in the community would like to submit a pull request with the Jackson
>> lib version upgrade?
>> Here's the open task: https://java.net/jira/browse/JERSEY-2107 (I have
>> scheduled it for Jersey 2.6)
>>
>> Marek
>>
>> On 14 Dec 2013, at 04:03, Robert DiFalco <robert.difalco_at_gmail.com> wrote:
>>
>> Just a heads up so that people don't have to deal with the craziness I just
>> went through.
>>
>> Setting up Jersey 2.4.1 to work with Jackson is exceedingly simple, that is
>> unless you read the Jersey tutorials and documentation.
>>
>> The JacksonFeature will pull in Jackson 1.9! I don't really think anyone
>> uses this version anymore, most of us use fasterxml 2.x.
>>
>> Just do this:
>>
>> public class RestApplication extends ResourceConfig {
>> public RestApplication() {
>> packages( "com.myapp.rest", "com.fasterxml.jackson.jaxrs.base" );
>> }
>> }
>>
>> Then add this to your pom.xml:
>>
>> <dependency>
>> <groupId>com.fasterxml.jackson.core</groupId>
>> <artifactId>jackson-databind</artifactId>
>> <version>${jackson.version}</version>
>> </dependency>
>> <dependency>
>> <groupId>com.fasterxml.jackson.jaxrs</groupId>
>> <artifactId>jackson-jaxrs-json-provider</artifactId>
>> <version>${jackson.version}</version>
>> </dependency>
>>
>> Completely forget about JacksonFeature AND DO NOT PUT THIS IN YOUR pom.xml:
>>
>> <dependency>
>> <groupId>org.glassfish.jersey.media</groupId>
>> <artifactId>jersey-media-json-jackson</artifactId>
>> <version>${jersey.version}</version>
>> </dependency>
>>
>> It's super simple, everyone seems to make it complicated. Now, listen, this
>> is trial and error so maybe there is a reason for all of the complexity that
>> the Jersey docs suggest for Jackson or all the blogs and stack overflow
>> answers. But Just the two jackson pom entries and the fasterxml provider
>> path is all I needed to use Jackson 2.3.0.
>>
>>
>>
>>
>>
>>