johnzon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Markus Karg <k...@quipsy.de>
Subject AW: User Question: Complex Adapters
Date Wed, 02 Oct 2019 08:06:52 GMT
Romain,

regarding point 1 I assume my detectings will be gone then -- will check after 1.2.1 is finally
published. Thanks! :-)

Regarding 2 is the problem that Johnzon simply cannot handle this OR that JSON-B simply does
not specifiy how to deal with non-instantiable classes?

Thanks a lot!
-Markus

-----Ursprüngliche Nachricht-----
Von: Romain Manni-Bucau <rmannibucau@gmail.com> 
Gesendet: Dienstag, 1. Oktober 2019 18:24
An: dev@johnzon.apache.org
Betreff: Re: User Question: Complex Adapters

Assuming last spec is JSON-B ;)

A few points to maybe be more accurate in the sample:

1. You can map root level object but Arne fixed some cases in 1.2.1, not
1.2.0
2. If you dont have a valid constructor it is undefined if it must be supported - I am assuming
it is not and think it is not doable in johnzon currently



Le mar. 1 oct. 2019 à 17:39, Markus Karg <karg@quipsy.de> a écrit :

> Romain,
>
> thank you for this interesting analysis! In fact I think the cause is 
> actually more simple and has nothing to do with cardinality, Map or 
> Map.Entry etc.: It is impossible to use Adapters on the top level OR 
> adapters must not adapt upon custom types (even when they are mappable)!
>
> Proof see below. Question: Is that wanted by JSON-B spec or is that a 
> bug in Johnzon?
>
>  public static void main(String[] a) {
>       // Should parse JSON to Foo, then map Foo to Bar, but actually 
> tries to parse JSON to Bar directly, IGNORING the mapper!
>       JsonbConfig jsonbConfig = new JsonbConfig().withAdapters(new 
> FooBarMapper());
>       Jsonb jsonb = JsonbBuilder.create(jsonbConfig);
>       System.out.println(jsonb.fromJson("{ }", Foo.class)); // works 
> well
> :-)
>       System.out.println(jsonb.fromJson("{ }", Bar.class)); // 
> FooBarMapper is NOT invoked -> Johnzon tries to create Bar instance 
> :-( }
>
> public static class Foo { }
>
> @JsonbTypeAdapter(FooBarMapper.class) private static class Bar {
>     Bar(int jsonCannotCallThis) { }
> }
>
> public static class FooBarMapper implements JsonbAdapter<Bar, Foo> {
>         @Override public Foo adaptToJson(Bar obj) throws Exception { 
> return new Foo(); }
>         @Override public Bar adaptFromJson(Foo obj) throws Exception 
> {return new Bar(1); }
>     }
>
> I know, I can solve with a Deserializer. What I like to reach is to 
> clarify whether this is a bug in Johnzon (so we need to fix it) or 
> whether this is as wanted by JSON-P spec, so we should improve the JavaDocs there.
> :-)
>
> -Markus
>
>
> -----Ursprüngliche Nachricht-----
> Von: Romain Manni-Bucau <rmannibucau@gmail.com>
> Gesendet: Dienstag, 1. Oktober 2019 16:50
> An: dev@johnzon.apache.org
> Betreff: Re: User Question: Complex Adapters
>
> Le mar. 1 oct. 2019 à 16:36, Markus Karg <karg@quipsy.de> a écrit :
>
> > Romain,
> >
> > thanks for your ideas. As always, they are very valueable. 😊
> >
> > I assume that a Deserializer would actually work and *workaround* 
> > the current problem (which is fine for now). But my question really is:
> > Isn't the word "cardinality" missing in the Spec then? And what if I 
> > actually want to map a collection to an int by let's say return the 
> > count of ist entries... (yes, hypothethical, just to make you 
> > understand my point: this is nowhere forbidden by the spec)?
> >
>
> Well spec explains how  a map is mapped not how a nested object of an 
> object is automatically mapped so it sounds explicitly not handled to me.
>
>
>
> > The container level actually is there, but not visible to Johnzon: 
> > The adapter actually does the cardinality change in its 
> > *implementation* (not in its *declaration*), as it simply picks the 
> > first entry in the map. In fact I do not find anything in JSON-B 
> > spec nor JavaDocs that both sides of the adapter MUST have the same 
> > cardinality, as the spec and JavaDocs for adapters *just* say that 
> > any umappable class has to be adapted to "just some" mappable class 
> > (without a word about
> > cardinality) -- and Map apparently *is* "just some" mappable class.
> >
>
> It is not needed but your Entry has no link with the json so it would 
> fail anyway.
>
> Note that the underlying is not cardinality but object mapping (and 
> 100% relies on the signatures in jsonb - johnzon has a programmatic 
> alternative but it is not needed here).
>
> I suspect here the map type is the issue since it is handled ad-hoc 
> and bypasses adapters.
>
> We could add a toggle to disable that since spec does not say anything 
> on that but we would keep current behavior until the johnzon toggle is 
> enabled for compatibility reasons (we just did a 1.2, i prefer to 
> avoid a 1.3 less than a month after ;)).
>
>
> > Wdyt?
> >
> > -Markus
> >
> >
> > -----Ursprüngliche Nachricht-----
> > Von: Romain Manni-Bucau <rmannibucau@gmail.com>
> > Gesendet: Dienstag, 1. Oktober 2019 16:24
> > An: dev@johnzon.apache.org
> > Betreff: Re: User Question: Complex Adapters
> >
> > Hi Markus,
> >
> > Map does not match Map.Entry so it does not work ;)
> >
> > Semantically you miss a level of "container" (a map is a kind of 
> > List<Map.Entry> even if structurally it does not match).
> > Also note that Map.Entry is modelized per its signatures as a 
> > {key:...,
> > value: ....} and not as {key:value} as in a map.
> >
> > I guess a Deserializer can be closer than an adapter of what you are 
> > trying to do.
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog < 
> > https://rmannibucau.metawerx.net/> | Old Blog < 
> > http://rmannibucau.wordpress.com> | Github 
> > <https://github.com/rmannibucau>
> > | LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book <
> > https://www.packtpub.com/application-development/java-ee-8-high-perf
> > or
> > mance
> > >
> >
> >
> > Le mar. 1 oct. 2019 à 16:17, Markus Karg <karg@quipsy.de> a écrit :
> >
> > > I’d be very very glad if you could answer a short user question 
> > > I’m completely stuck with. 😊
> > >
> > > Johnzon is able to parse JSON object into Java Map while 
> > > respecting custom
> > > adapters:
> > >
> > > // Works well: Uses custom Adapter<UUID, String> Map<UUID, Foo>

> > > map = jsonb.fromJson("{ \"" + uuid + "\": { \"name\":
> > > \"Lala\" } }", new JohnzonParameterizedType(Map.class, UUID.class, 
> > > Foo.class));
> > >
> > > Now let’s assume we do not want to get a complete Map but just a 
> > > single Map.Entry, as we know for sure the JSON string only 
> > > contains exactly just one single key-value-pair:
> > >
> > > JsonbConfig jsonbConfig = new JsonbConfig().withAdapters(new 
> > > UuidAdapter(), new MapEntryAdapter<UUID, Foo>());
> > >
> > > // Fails with "Can't map Entry<UUID, Foo>"
> > > Map.Entry<UUID, Foo> entry = jsonb.fromJson("{ \"" + uuid + "\": {
> > > \"name\": \"Lala\" } }", new
> > > JohnzonParameterizedType(Map.Entry.class,
> > > UUID.class, Foo.class));
> > >
> > > public class MapEntryAdapter<K, V> implements 
> > > JsonbAdapter<Map.Entry<K,
> > > V>, Map<K, V>> {
> > >     @Override public Map<K, V> adaptToJson(Entry<K, V> obj) throws

> > > Exception { … }
> > >     @Override public Entry<K, V> adaptFromJson(Map<K, V> obj) 
> > > throws Exception { … } }
> > >
> > > Strange but true, this does not work but complains it cannot map 
> > > Entry<UUID, Foo> -- it seems it cannot „see“ the correctly 
> > > registered adapter (not even if I replace <K, V> by <UUID, String>

> > > manually in the code).
> > >
> > > So the question is: Where is the fault? Did I try something 
> > > (what?) which is forbidden in JSON-B? Is this a bug in Johnzon?
> > >
> > > Actually I assume it is my personal fault (as so often), but I 
> > > just cannot see where… 😉
> > >
> > > Thanks a lot for your kind help!
> > > -Markus
> > >
> > >
> > >
> >
>
Mime
View raw message