users@jersey.java.net

[Jersey] Re: How Do I Provide a Custom ObjectMapper?

From: Robert DiFalco <robert.difalco_at_gmail.com>
Date: Fri, 10 Jan 2014 18:32:12 -0800

He knows.

Sent from my iPhone

> On Jan 10, 2014, at 6:29 PM, cowwoc <cowwoc_at_bbs.darktech.org> wrote:
>
> So please bring this to Tatu's attention. I'm pretty sure he had a good reason to define META-INF/services. It's possible that somewhere down the line Jersey's registration changed, and Tatu didn't notice. Either way, please let him know by filing a bug report.
>
> Gili
>
>> On 10/01/2014 9:16 PM, Robert DiFalco wrote:
>> This is actually a Jackson 2.x bug. They shouldn't be putting their providers in the META-INF.services entry. I don't think it is a Jersey behavior to load this by default. I think it is a Java standard sort of thing.
>>
>>
>> On Fri, Jan 10, 2014 at 6:09 PM, cowwoc <cowwoc_at_bbs.darktech.org> wrote:
>>> I suggest filing a bug to improve this behavior.
>>>
>>> Gili
>>>
>>>> On 10/01/2014 3:09 PM, Michael Iles wrote:
>>>> I also went down the road of turning off the META-INF services lookup
>>>> (using properties, same as you) but it broke other things (I think it
>>>> broke the Jersey/Spring bridge) and I didn't have the patience to
>>>> track down the new set of problems.
>>>>
>>>> In the end I've adopted the approach you suggested on SO and I simply
>>>> delete the META-INF/services dir from the Jackson provider jar. That
>>>> way Jersey can happily auto-discover everything except for Jackson,
>>>> and I can register Jackson by hand with the proper configuration.
>>>>
>>>> Mike.
>>>>
>>>>> On 10 January 2014 14:54, Robert DiFalco <robert.difalco_at_gmail.com> wrote:
>>>>> This is what I do. Jackson defines services in its META-INF jar entry so you
>>>>> will still get those. But the ones used below will be the ones used. Then
>>>>> you can modify this code to configure them any way you want:
>>>>>
>>>>> public class JacksonFeature implements Feature {
>>>>>
>>>>> public boolean configure( final FeatureContext context ) {
>>>>>
>>>>> String postfix = '.' +
>>>>> context.getConfiguration().getRuntimeType().name().toLowerCase();
>>>>>
>>>>> context.property( CommonProperties.MOXY_JSON_FEATURE_DISABLE +
>>>>> postfix, true );
>>>>>
>>>>> context.register( JsonParseExceptionMapper.class );
>>>>> context.register( JsonMappingExceptionMapper.class );
>>>>> context.register( JSON_PROVIDER, MessageBodyReader.class,
>>>>> MessageBodyWriter.class );
>>>>>
>>>>> return true;
>>>>> }
>>>>>
>>>>> private static final JacksonJsonProvider JSON_PROVIDER =
>>>>> new JacksonJsonProvider( JsonUtils.getSharedObjectMapper() );
>>>>> }
>>>>>
>>>>> Then my rest application looks like the following. Notice that I disable the
>>>>> META-INF stuff, for me that works, but it is probably not a very safe thing
>>>>> to do. It should work fine with out those being disabled.
>>>>>
>>>>> public class RestApplication extends ResourceConfig {
>>>>>
>>>>> public RestApplication() {
>>>>> property( ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, true );
>>>>> property( ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true );
>>>>>
>>>>> packages( "com.myapp.rest.services" );
>>>>>
>>>>> register( new GZipEncoder() );
>>>>> register( JacksonFeature.class );
>>>>> }
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> On Wed, Jan 8, 2014 at 9:30 PM, Michael Iles <michael.iles_at_gmail.com> wrote:
>>>>>> I need to provide a custom Jackson ObjectMapper to Jersey so that I
>>>>>> can register the Joda Time module with it and configure other things
>>>>>> like FAIL_ON_EMPTY_BEANS, etc.
>>>>>>
>>>>>> In Jersey 1 I gave a @Provider which implemented
>>>>>> ContextResolver<ObjectMapper> to give my custom OjbectMapper.
>>>>>>
>>>>>> In Jersey 2 I bring in the jackson-jaxrs-json-provider artifact which
>>>>>> auto-registers itself with Jersey. However I want to *manually*
>>>>>> register it, so that I can customize it:
>>>>>>
>>>>>> public class MyApplication extends ResourceConfig {
>>>>>>
>>>>>> public MyApplication() {
>>>>>> JacksonJaxbJsonProvider provider = new
>>>>>> JacksonJaxbJsonProvider();
>>>>>> provider.setMapper(Marshaller.instance.objectMapper);
>>>>>> register(provider);
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> My problem is now that I have *two* Jackson providers registered with
>>>>>> Jersey:
>>>>>>
>>>>>> 2014-01-08 23:50:38,823 [main]
>>>>>> org.glassfish.jersey.server.ApplicationHandler:558 INFO Jersey
>>>>>> application initialized.
>>>>>> Root Resource Classes:
>>>>>> ...
>>>>>> Message Body Readers:
>>>>>> com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
>>>>>> com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider
>>>>>> ...
>>>>>> Message Body Writers:
>>>>>> com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
>>>>>> com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider
>>>>>> ...
>>>>>>
>>>>>> What's the right way to do this? I either want to get access to the
>>>>>> Jackson provider that Jersey auto-discovered (so that I can change its
>>>>>> ObjectMapper) or I want to stop the auto-discovery so that I can
>>>>>> register my own Jackson provider.
>>>>>>
>>>>>> Mike
>