hey guys,
I recently wanted to upgrade to fasterxml jackson 2.2.0 (was on 2.1.4)
and noticed the changes they have made to their Provider breaks
how current ProviderFactory in cxf jax-rs looks up a message writer/reader.
Here are the details and I would like to hear what you guys think
on how to procede with this.
I'm using cxf 2.7.4
first up let's look at Providerfactory and specifically
private static Type[] getGenericInterfaces(Class<?> cls) {
if (Object.class == cls) {
return new Type[]{};
}
Type genericSuperCls = cls.getGenericSuperclass();
if (genericSuperCls instanceof ParameterizedType) {
return new Type[]{genericSuperCls};
}
Type[] types = cls.getGenericInterfaces();
if (types.length > 0) {
return types;
}
return getGenericInterfaces(cls.getSuperclass());
}
which is called from handleMapper(...);
on fasterxml jackson 2.1.4 it works fine because here is how the class is
declared in there
com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider:
@Provider
@Consumes(MediaType.WILDCARD) // NOTE: required to support "non-standard" JSON
variants
@Produces(MediaType.WILDCARD)
public class JacksonJsonProvider
implements
MessageBodyReader<Object>,
MessageBodyWriter<Object>,
Versioned
{
this leads to grabbing the generic interfaces and since Object is handled it
can handle
writing your models fine.
now in 2.2.0 it's been modified to be like this
@Provider
@Consumes(MediaType.WILDCARD) // NOTE: required to support "non-standard" JSON
variants
@Produces(MediaType.WILDCARD)
public class JacksonJsonProvider
extends ProviderBase<JacksonJsonProvider,
ObjectMapper,
JsonEndpointConfig, JsonMapperConfigurator>
{
it's been refactored to extend ProviderBase which is delcared as so:
public abstract class ProviderBase<
THIS extends ProviderBase<THIS, MAPPER, EP_CONFIG, MAPPER_CONFIG>,
MAPPER extends ObjectMapper,
EP_CONFIG extends EndpointConfigBase<EP_CONFIG>,
MAPPER_CONFIG extends MapperConfiguratorBase<MAPPER_CONFIG,MAPPER>
>
implements
MessageBodyReader<Object>,
MessageBodyWriter<Object>,
Versioned
{
now what happens when getGenericInterfaces(...) is called now we hit this:
Type genericSuperCls = cls.getGenericSuperclass();
if (genericSuperCls instanceof ParameterizedType) {
return new Type[]{genericSuperCls};
}
and in handleMapper we end up grabbing the parameterized types
which in this case are <JacksonJsonProvider, ObjectMapper, JsonEndpointConfig,
JsonMapperConfigurator>
and end up having no match for a body writer/reader.
Shouldn't getGenericInterfaces been fixed so as to also return the actual
interfaces of the class/superclass
in this case
implements
MessageBodyReader<Object>,
MessageBodyWriter<Object>,
Versioned
It seems to me that only looking at ParameterizedType and returning early
leaves out the actual interfaces that a Provider normally implements.
For now we are back on 2.1.4 of fasterxml jackson and cxf 2.7.4 but
eventually we would like to move 2.2.+
thanks,
parwiz