Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add failing test for dynamic typing #60

Merged
merged 1 commit into from
Mar 18, 2015
Merged

Conversation

jhaber
Copy link
Contributor

@jhaber jhaber commented Mar 10, 2015

We just upgraded from Jackson 2.1.1 to Jackson 2.3.5 and encountered a regression in the way dynamic typing is handled. It seems that if you have a resource that returns a list, static typing is always used to serialize the list contents, even though the mapper has dynamic typing enabled. Returning a single object works fine (dynamic typing is used), it is only once you wrap in a list that the problem occurs. This PR adds two tests. The first one returns a single object and passes, and the second one returns a list and fails (the z field isn't serialized because of static typing). This test fails when running Jackson 2.3.5, 2.4.5, 2.5.1, and against master (but this behavior worked in 2.1.1).

I think the issue arises because ProviderBase calls withType here, and at some point it seems like that method was changed to force static typing here.

I don't know enough about the internals to suggest a fix, but our workaround for now has been to add an ObjectWriterModifier that returns w.withType((JavaType) null);

@jhaber
Copy link
Contributor Author

jhaber commented Mar 10, 2015

It seems like it works in the single object case because this line prevents withType from being called, and the comments seem to suggest that it is known that this would break polymorphic type serialization 😢

@jhaber
Copy link
Contributor Author

jhaber commented Mar 18, 2015

@cowtowncoder thoughts?

@cowtowncoder
Copy link
Member

Unfortunately haven't had time to look, I can do that today.

cowtowncoder added a commit that referenced this pull request Mar 18, 2015
Add failing test for dynamic typing
@cowtowncoder cowtowncoder merged commit 3d521cf into FasterXML:master Mar 18, 2015
@cowtowncoder
Copy link
Member

... also, I know it's not of much help when you have made the mistake, but my belief is that one should never read or write non-Object JSON data by resource. Lists and Maps are source of endless issues with generic types, and even more so with polymorphic types. So while it may seem silly to have a wrapper, I consider it a best practice at this point.

@cowtowncoder
Copy link
Member

Ok. This does look tricky. I am surprised that code should work, if type is not specified -- I would expect it then not to output type information at all, as it would be unable to determine base type of elements within List. I'll try to see if I can untangle something. My concern in avoiding setting of type is simply that doing that may produce other fails, although with limited amount of unit tests via JAX-RS might not break tests (unfortunately).

@cowtowncoder
Copy link
Member

Ah. Got it. So the test case is polymorphic in Java, but not from Jackson perspective -- and this is why specifying exact type causes issues. Had Point been polymorphic with @JsonTypeInfo, it would actually work as expected.

Conversely, it is not possible to simply prevent forcing of type info for all Collections (and perhaps Maps), as that would break polymorphic container handling. Turns out there is one unit test for that, even, TestRootType.

But there is some hope, perhaps for 2.6: this is an example of the problem between specifying base type to use for (polymorphic) type handling, compared to actual type to use for finding serializer. I have known there is the gap for a while, but haven't yet bumped into specific failure case.
This is such a case...

@jhaber
Copy link
Contributor Author

jhaber commented Mar 19, 2015

Interesting, for whats it's worth we haven't run into any problems using our current ObjectWriterModifier but we don't use @JsonTypeInfo heavily.

I see the test failure with TestRootType but I don't understand why it fails, can't it respect the @JsonTypeInfo without needing to have withType called? I swapped @JsonTypeInfo for @JsonSerialize(using = CustomSerializer.class) and that seemed to work fine without calling withType

@cowtowncoder
Copy link
Member

Right, what happens is that without call, signature would be seen as List<?>, and generally @JsonTypeInfo would be ignored because nominal base type (Object.class, since ? does not have any other information) does not have it. This is the reason call to enforce typing was added.

This is not a JAX-RS specific issue (there are other related), but is due to combination of Java type erasure (instances do NOT have generic signature; only method return type and parameters do), and difference Jackson makes between polymorphic base type and instance type. Latter can be determined from value, former not. So ideally for 2.6 there would be a way to pass information to correctly handle base type (for possible polymorphic handling) without overriding instance type (where applicable).

I will file a separate issue for jackson-databind; but for now your work-around is needed for your use case.

@jhaber
Copy link
Contributor Author

jhaber commented Mar 19, 2015

Great, thanks

@cowtowncoder
Copy link
Member

@HiJon89 Forgot to mention one obvious (if not convenient) work-around that does not require changes to ObjectWriterModifier' -- changing type from, sayList` to, say:

static class BaseList extends ArrayList<Base> { }

would also prevent issues since base type is only forced for generic types, and while BaseList is indirectly generic, it is not directly so.

cowtowncoder added a commit that referenced this pull request Mar 19, 2015
@cowtowncoder
Copy link
Member

Turns out that the change to fix this in jackson-databind is easy and does not cause any other failures.
That's not a guarantee there could not be some side-effects, but for now I assume it is proper way to fix this. But I'll keep that in 2.6.0 to avoid any regressions in patch versions.

Thank you again for reporting this!

@jhaber
Copy link
Contributor Author

jhaber commented Mar 20, 2015

Awesome! I'll watch for that release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants