Closed bpasson closed 3 months ago
@bpasson we don't really have many active maintainers of this repo.
I would suggest that this method is a good one to look at if anyone has an interest in trying to fix this.
First things first: never use this line in Jackson problem reproductions:
@JsonIgnoreProperties(ignoreUnknown = true)
as that is known to hide issues left and right and wasting everyone's time. (not saying it does so here but in the past has been big time sink).
Second: @pjfanning is probably right that specific handling XML backend needs is related to that method.
Third: one thing that can help with troubleshooting is to contribute failing (minimal) unit test (under src/test/java/../failing
) as a PR -- that saves time in multiple ways, including ensuring that the issue reported is fully understood.
@cowtowncoder I added a PR to branch 2.18 which contains the failing test. I did some debugging and found the following piece of code in the BasicDeserializerFactory
located at BasicDeserializerFactory.java#L2115
if (rawType == CLASS_ITERABLE) {
// [databind#199]: Can and should 'upgrade' to a Collection type:
TypeFactory tf = ctxt.getTypeFactory();
JavaType[] tps = tf.findTypeParameters(type, CLASS_ITERABLE);
JavaType elemType = (tps == null || tps.length != 1) ? TypeFactory.unknownType() : tps[0];
CollectionType ct = tf.constructCollectionType(Collection.class, elemType);
// Should we re-introspect beanDesc? For now let's not...
return createCollectionDeserializer(ctxt, ct, beanDesc);
}
It upgrades Iterable
from a simple type to a collection type, but the type in TypeUtil
in the method below it is still seen as a simple type.
It this related to the comment // Should we re-introspect beanDesc? For now let's not...
?
Ok, so no, that comment should not be relevant for this purpose (or problem).
But the call to TypeUtil
happens before call to BasicDeserializerFactory
, I think; and even if not, type "upgrade" only affects local processing.
Or put another way: two are not directly linked, TypeUtil
call is for adding external handling outside of deserializer to deal with possible wrapping.
Still, isIterationType()
should cover JavaType
here so maybe this is not the problem.
@cowtowncoder I did a test and Iterable
is marked as a simple type and isIterationType()
returns false.
If I extend the if clause in TypeUtil
to also check the raw class for Iterable
the failing test succeeds. This points to a deeper issue where Iterable
is classified wrong.
What do you think? If it is classified as an IterationType
it should work, although I have no idea what the impact is.
It might even make the explicit upgrading in BasicDeserializerFactory
obsolete, but you know more about why it is there than I.
@bpasson I think my concern was with the fact that Iterable
is more generic and less specific in some sense than Iterator
and as such addition of IterationType
did not include it on purpose. Original issue:
https://github.com/FasterXML/jackson-databind/issues/3950
does not mention this so I guess it could also be an oversight.
Especially since it is not about something else implementing Iterable
but specific type, see:
so... it could be something to improve. I will file an issue for that.
Having said that, I think addition in TypeUtil
for specific logic wrt Iterable
would probably make most sense here; even if logic in databind gets updated this change would still work.
@cowtowncoder That sounds sensible. I will update the PR to have TypeUtil
explicitly check for Iterable
to fix the issue.
The PR now is targeted at 2.18 branch. Is that ok or should I target it at main?
There is no main branch and master branch is for 3.0. 2.18 will be released before 3.0.
@bpasson Like @pjfanning mentioned, we'll go with 2.x.
But this looks quite safe change so I would accept it against 2.17 as well (for 2.17.1); that will be released before 2.18.0 (as we only just started 2.18 branch, it'll be multiple months).
@cowtowncoder I opened the PR to 2.17. It contains the fix and I moved the original failing, now working, testcase to the lists test package.
Fix merged in for 2.17.1.
When using builder classes with method signatures like
Builder orderLines(Iterable<? extends OrderLine> lines)
for collections, deserialization fails with the following.A reproducer can be found at https://github.com/bpasson/jackson-dataformat-xml-issue-646
This concerns jackson-dataformat-xml version 2.17.0.
Detailed Example
Consider the following objects:
When deserializing the following XMl document:
Deserializing fails with:
This is caused by the following builder method:
If you use
Iterable<? extends OrderLine>
as method parameter it fails. If you useCollection<? extends OrderLine>
, see commented line above, it works. I expected both to work as is the case for Json binding.