7

I'm using Jackson (in Jersey) to serialize entities, and I'm migrating from Jackson 1.9 to 2.0. I followed this guide, and at first it seemed like everything worked out easily.

But a closer look reveals that Jackson 1.9 is still being used to serialize my responses, and therefore ignoring my (migrated) Jackson 2.0 annotation. You can see which annotations I'm using in the following code fragment:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public abstract class IdEntity {

@Id
@JsonDeserialize(using = ObjectIdJsonDeserializer.class)
protected ObjectId id;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonSerialize(using = ObjectIdJsonSerializer.class)
public ObjectId getId() {
    return id;
}

public void setId(ObjectId id) {
    this.id = id;
}

@JsonIgnore
public String getIdAsString() {
    return id == null ? "" : id.toString();
}

My @JsonIgnore getters are getting serialized, and my ObjectIdJsonSerializer isn't being used for the ObjectId field.

In debug I can see that the ObjectMapper being used is from 1.9.

I've removed all the direct maven dependencies to Jackson 1.9, and tried adding exclusions to jersey-json, to prevent it from pulling in Jackson 1.9. But I can't get rid of it entirely (by putting an exclusion to all the codehaus.jackson stuff in my dependency management) because I'm also using Spring AMQP, which needs Jackson 1.9.

Any ideas on how to manage this? Has anyone encountered / solved a similar problem? How do I force Jersey to use Jackson 2.0?

Eyal
  • 3,412
  • 1
  • 44
  • 60

4 Answers4

8

I'm answering my own question, based on the (useful) answers from StaxMan and pgelinas.

I had to do two things to make it work.

The first things was to remove the com.sun.jersey.api.json.POJOMappingFeature from my web.xml.

The second was to update my jackson-jaxrs-json-provider (actually, all of my Jackson artifacts) to 2.1.

With 2.1 or 2.0, and POJOMappingFeature, Jackson 1.9 was still being used for serialization.

With 2.0, and POJOMappingFeature removed, I got a missing message body writer error.

With 2.1 and POJOMappingFeature removed, everything worked as expected.

Eyal
  • 3,412
  • 1
  • 44
  • 60
5

It is not enough to simply upgrade Jackson core and mapper versions; integration between Jersey (or any JAX-RS implementation) and Jackson happens using specific JAX-RS provider. For Jackson, this would be https://github.com/FasterXML/jackson-jaxrs-json-provider.

So you also need to add 2.x Jackson JAX-RS JSON provider, and that will make Jersey use Jackson 2.x for its operation.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
2

I would double-check if you don't have both versions of Jackson in your classpath. The package names in Jackson 2.x got changed to com.fasterxml from org.codehaus. This way you don't have some cryptic classpath problem (like a NoClassDefFound), but if you don't use the proper packages this is the kind of behavior that you'll see.

Also, the annotations were extracted into their own project, jackson-annotations.

Pascal Gélinas
  • 2,744
  • 19
  • 20
  • No, I'm using Maven and I replaced all the org.codehaus artifacts with their respective fasterxml versions. I used [this guide](http://www.cowtowncoder.com/blog/archives/2012/04/entry_469.html) to do the migration. – Eyal Apr 08 '13 at 17:25
  • 2
    That I understood. What I'm saying is that perhaps another project (Jersey?) might include Jackson 1.x as a transitive dependency and add it to the classpath, and perhaps that it is this version that is used as the JAX-RS provider. If I recall correctly, it's possible to inspect the dependencies of a project with maven, you should use that. – Pascal Gélinas Apr 09 '13 at 14:17
  • Jersey brings in old Jackson dependencies, but they seem to be compile-time, so I'm not sure that's the issue. I will definitely check this out, of course :-) – Eyal Apr 09 '13 at 14:28
  • I can't remove the old Jackson 1.x dependencies entirely, since they're being used in another area (by Spring AMQP). However, all my annotations are from the Jackson 2.0 "fasterxml" namespace, so how could the older Jackson 1.x code work (at all) as a JAX-RS provider? – Eyal Apr 09 '13 at 16:26
  • Jackson doesn't need annotation to work, it can detect properties to use with bean convention; if the classes are pure Java Beans, it will work without you doing anything. Of course, if you need advanced features you need the annotations. – Pascal Gélinas Apr 10 '13 at 13:45
-1

even if you upgrade to jackson 2 you will have NoClassfound error as spring using old jackson.

Check spring implementation on this link: http://git.springsource.org/sandbox/cbeams/blobs/4731d671cbeb82b87dd0f10e16cd09d8f267b433/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/json/MappingJacksonJsonView.java

patel
  • 1
  • This might be true for Spring MVC (as per the link you posted) but I'm not using it, only other Spring packages. – Eyal Aug 29 '13 at 07:58