You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@johnzon.apache.org by Markus Karg <ka...@quipsy.de> on 2019/10/01 14:07:36 UTC

User Question: Complex Adapters

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



Re: User Question: Complex Adapters

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Then, and until somebody see how an impl can do that, I guess spec must
just explicit it is not intended to work IMHO.

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-performance>


Le mer. 2 oct. 2019 à 12:03, Markus Karg <ka...@quipsy.de> a écrit :

> Just for the reconds: I do not say that the second option MUST work; I
> just say I want to clarify IF the spec wants Johnzon to support that OR if
> the spec instead should clearly limit the word "mapable" to "those few
> namely listed in spec".
>
> -----Ursprüngliche Nachricht-----
> Von: Romain Manni-Bucau <rm...@gmail.com>
> Gesendet: Mittwoch, 2. Oktober 2019 11:51
> An: dev@johnzon.apache.org
> Betreff: Re: User Question: Complex Adapters
>
> No issue Markus and I was actually not defensive, I just don't see how the
> second can be implemented without breaking the full Jsonb context. In the
> impl you miss part of the types to do the second option.
>
> (yes, it also means adapters are not that usable outside "primitive" types
> - primitives, string, JsonValues).
>
> 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-performance
> >
>
>
> Le mer. 2 oct. 2019 à 11:47, Markus Karg <ka...@quipsy.de> a écrit :
>
> > Romain,
> >
> > as I said, since the actual problem can be solved with a Deserializer,
> > in fact the sole left over discussion is reduced to how to actually
> > interprete the JavaDocs of adapter. It literally says "The target type
> > could be string or some mappable java type.". So what means
> > "mappable", does it mean "the name of the class is directly mentioned
> > in the spec" or does it mean "any class which Jsonb.fromJson will
> > produce even if an adapter or deserializer is needed for it". It
> > seems, Johnzon implements the first option and fails with the second.
> > My target is not to force any new features or find a workaround. My
> > target is to either open a bug report with Johnzon (to fix broken
> > support), OR to open a bug report with JSON-B (to have a clear
> definition in the JavaDocs).
> >
> > -Markus
> >
> >
> > -----Ursprüngliche Nachricht-----
> > Von: Romain Manni-Bucau <rm...@gmail.com>
> > Gesendet: Mittwoch, 2. Oktober 2019 11:11
> > An: dev@johnzon.apache.org
> > Betreff: Re: User Question: Complex Adapters
> >
> > I have to admit I'm a bit lost, cause even if I agree Johnzon can be
> > better at handling adapters (there are several cases they would be
> > skipped or only work if target type is String) but I also don't see
> > how you use case should work.
> > Can you try to explicit the workflow you expect? Here is where I fail
> > to see it working:
> >
> > 1. you ask a Map.Entry and Johnzon sees a JsonObject (you don't get a
> > Map, it is on java side and you never specify to deserializer a Map)
> > 2. johnzon tries to match a Map.Entry converter (deserializer more
> > than adapter at that level), does not find it 3. johnzon tries to
> > instantiate that entry but can't and fail
> >
> > Sounds legit to me at the end. Where do you expect another workflow?
> >
> >
> > 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-perfor
> > mance
> > >
> >
> >
> > Le mer. 2 oct. 2019 à 10:08, Markus Karg <ka...@quipsy.de> a écrit :
> >
> > > 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 <rm...@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 <ka...@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 <rm...@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 <ka...@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 <rm...@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-
> > > > > pe
> > > > > rf
> > > > > or
> > > > > mance
> > > > > >
> > > > >
> > > > >
> > > > > Le mar. 1 oct. 2019 à 16:17, Markus Karg <ka...@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
> > > > > >
> > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

AW: User Question: Complex Adapters

Posted by Markus Karg <ka...@quipsy.de>.
Just for the reconds: I do not say that the second option MUST work; I just say I want to clarify IF the spec wants Johnzon to support that OR if the spec instead should clearly limit the word "mapable" to "those few namely listed in spec".

-----Ursprüngliche Nachricht-----
Von: Romain Manni-Bucau <rm...@gmail.com> 
Gesendet: Mittwoch, 2. Oktober 2019 11:51
An: dev@johnzon.apache.org
Betreff: Re: User Question: Complex Adapters

No issue Markus and I was actually not defensive, I just don't see how the second can be implemented without breaking the full Jsonb context. In the impl you miss part of the types to do the second option.

(yes, it also means adapters are not that usable outside "primitive" types
- primitives, string, JsonValues).

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-performance>


Le mer. 2 oct. 2019 à 11:47, Markus Karg <ka...@quipsy.de> a écrit :

> Romain,
>
> as I said, since the actual problem can be solved with a Deserializer, 
> in fact the sole left over discussion is reduced to how to actually 
> interprete the JavaDocs of adapter. It literally says "The target type 
> could be string or some mappable java type.". So what means 
> "mappable", does it mean "the name of the class is directly mentioned 
> in the spec" or does it mean "any class which Jsonb.fromJson will 
> produce even if an adapter or deserializer is needed for it". It 
> seems, Johnzon implements the first option and fails with the second. 
> My target is not to force any new features or find a workaround. My 
> target is to either open a bug report with Johnzon (to fix broken 
> support), OR to open a bug report with JSON-B (to have a clear definition in the JavaDocs).
>
> -Markus
>
>
> -----Ursprüngliche Nachricht-----
> Von: Romain Manni-Bucau <rm...@gmail.com>
> Gesendet: Mittwoch, 2. Oktober 2019 11:11
> An: dev@johnzon.apache.org
> Betreff: Re: User Question: Complex Adapters
>
> I have to admit I'm a bit lost, cause even if I agree Johnzon can be 
> better at handling adapters (there are several cases they would be 
> skipped or only work if target type is String) but I also don't see 
> how you use case should work.
> Can you try to explicit the workflow you expect? Here is where I fail 
> to see it working:
>
> 1. you ask a Map.Entry and Johnzon sees a JsonObject (you don't get a 
> Map, it is on java side and you never specify to deserializer a Map) 
> 2. johnzon tries to match a Map.Entry converter (deserializer more 
> than adapter at that level), does not find it 3. johnzon tries to 
> instantiate that entry but can't and fail
>
> Sounds legit to me at the end. Where do you expect another workflow?
>
>
> 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-perfor
> mance
> >
>
>
> Le mer. 2 oct. 2019 à 10:08, Markus Karg <ka...@quipsy.de> a écrit :
>
> > 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 <rm...@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 <ka...@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 <rm...@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 <ka...@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 <rm...@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-
> > > > pe
> > > > rf
> > > > or
> > > > mance
> > > > >
> > > >
> > > >
> > > > Le mar. 1 oct. 2019 à 16:17, Markus Karg <ka...@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
> > > > >
> > > > >
> > > > >
> > > >
> > >
> >
>

Re: User Question: Complex Adapters

Posted by Romain Manni-Bucau <rm...@gmail.com>.
No issue Markus and I was actually not defensive, I just don't see how the
second can be implemented without breaking the full Jsonb context. In the
impl you miss part of the types to do the second option.

(yes, it also means adapters are not that usable outside "primitive" types
- primitives, string, JsonValues).

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-performance>


Le mer. 2 oct. 2019 à 11:47, Markus Karg <ka...@quipsy.de> a écrit :

> Romain,
>
> as I said, since the actual problem can be solved with a Deserializer, in
> fact the sole left over discussion is reduced to how to actually interprete
> the JavaDocs of adapter. It literally says "The target type could be string
> or some mappable java type.". So what means "mappable", does it mean "the
> name of the class is directly mentioned in the spec" or does it mean "any
> class which Jsonb.fromJson will produce even if an adapter or deserializer
> is needed for it". It seems, Johnzon implements the first option and fails
> with the second. My target is not to force any new features or find a
> workaround. My target is to either open a bug report with Johnzon (to fix
> broken support), OR to open a bug report with JSON-B (to have a clear
> definition in the JavaDocs).
>
> -Markus
>
>
> -----Ursprüngliche Nachricht-----
> Von: Romain Manni-Bucau <rm...@gmail.com>
> Gesendet: Mittwoch, 2. Oktober 2019 11:11
> An: dev@johnzon.apache.org
> Betreff: Re: User Question: Complex Adapters
>
> I have to admit I'm a bit lost, cause even if I agree Johnzon can be
> better at handling adapters (there are several cases they would be skipped
> or only work if target type is String) but I also don't see how you use
> case should work.
> Can you try to explicit the workflow you expect? Here is where I fail to
> see it working:
>
> 1. you ask a Map.Entry and Johnzon sees a JsonObject (you don't get a Map,
> it is on java side and you never specify to deserializer a Map) 2. johnzon
> tries to match a Map.Entry converter (deserializer more than adapter at
> that level), does not find it 3. johnzon tries to instantiate that entry
> but can't and fail
>
> Sounds legit to me at the end. Where do you expect another workflow?
>
>
> 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-performance
> >
>
>
> Le mer. 2 oct. 2019 à 10:08, Markus Karg <ka...@quipsy.de> a écrit :
>
> > 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 <rm...@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 <ka...@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 <rm...@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 <ka...@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 <rm...@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-pe
> > > > rf
> > > > or
> > > > mance
> > > > >
> > > >
> > > >
> > > > Le mar. 1 oct. 2019 à 16:17, Markus Karg <ka...@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
> > > > >
> > > > >
> > > > >
> > > >
> > >
> >
>

AW: User Question: Complex Adapters

Posted by Markus Karg <ka...@quipsy.de>.
Romain,

as I said, since the actual problem can be solved with a Deserializer, in fact the sole left over discussion is reduced to how to actually interprete the JavaDocs of adapter. It literally says "The target type could be string or some mappable java type.". So what means "mappable", does it mean "the name of the class is directly mentioned in the spec" or does it mean "any class which Jsonb.fromJson will produce even if an adapter or deserializer is needed for it". It seems, Johnzon implements the first option and fails with the second. My target is not to force any new features or find a workaround. My target is to either open a bug report with Johnzon (to fix broken support), OR to open a bug report with JSON-B (to have a clear definition in the JavaDocs).

-Markus


-----Ursprüngliche Nachricht-----
Von: Romain Manni-Bucau <rm...@gmail.com> 
Gesendet: Mittwoch, 2. Oktober 2019 11:11
An: dev@johnzon.apache.org
Betreff: Re: User Question: Complex Adapters

I have to admit I'm a bit lost, cause even if I agree Johnzon can be better at handling adapters (there are several cases they would be skipped or only work if target type is String) but I also don't see how you use case should work.
Can you try to explicit the workflow you expect? Here is where I fail to see it working:

1. you ask a Map.Entry and Johnzon sees a JsonObject (you don't get a Map, it is on java side and you never specify to deserializer a Map) 2. johnzon tries to match a Map.Entry converter (deserializer more than adapter at that level), does not find it 3. johnzon tries to instantiate that entry but can't and fail

Sounds legit to me at the end. Where do you expect another workflow?


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-performance>


Le mer. 2 oct. 2019 à 10:08, Markus Karg <ka...@quipsy.de> a écrit :

> 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 <rm...@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 <ka...@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 <rm...@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 <ka...@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 <rm...@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-pe
> > > rf
> > > or
> > > mance
> > > >
> > >
> > >
> > > Le mar. 1 oct. 2019 à 16:17, Markus Karg <ka...@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
> > > >
> > > >
> > > >
> > >
> >
>

Re: User Question: Complex Adapters

Posted by Romain Manni-Bucau <rm...@gmail.com>.
I have to admit I'm a bit lost, cause even if I agree Johnzon can be better
at handling adapters (there are several cases they would be skipped or only
work if target type is String) but I also don't see how you use case should
work.
Can you try to explicit the workflow you expect? Here is where I fail to
see it working:

1. you ask a Map.Entry and Johnzon sees a JsonObject (you don't get a Map,
it is on java side and you never specify to deserializer a Map)
2. johnzon tries to match a Map.Entry converter (deserializer more than
adapter at that level), does not find it
3. johnzon tries to instantiate that entry but can't and fail

Sounds legit to me at the end. Where do you expect another workflow?


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-performance>


Le mer. 2 oct. 2019 à 10:08, Markus Karg <ka...@quipsy.de> a écrit :

> 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 <rm...@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 <ka...@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 <rm...@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 <ka...@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 <rm...@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 <ka...@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
> > > >
> > > >
> > > >
> > >
> >
>

AW: User Question: Complex Adapters

Posted by Markus Karg <ka...@quipsy.de>.
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 <rm...@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 <ka...@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 <rm...@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 <ka...@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 <rm...@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 <ka...@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
> > >
> > >
> > >
> >
>

Re: User Question: Complex Adapters

Posted by Romain Manni-Bucau <rm...@gmail.com>.
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 <ka...@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 <rm...@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 <ka...@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 <rm...@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-perfor
> > mance
> > >
> >
> >
> > Le mar. 1 oct. 2019 à 16:17, Markus Karg <ka...@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
> > >
> > >
> > >
> >
>

AW: User Question: Complex Adapters

Posted by Markus Karg <ka...@quipsy.de>.
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 <rm...@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 <ka...@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 <rm...@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-perfor
> mance
> >
>
>
> Le mar. 1 oct. 2019 à 16:17, Markus Karg <ka...@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
> >
> >
> >
>

Re: User Question: Complex Adapters

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Le mar. 1 oct. 2019 à 16:36, Markus Karg <ka...@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 <rm...@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-performance
> >
>
>
> Le mar. 1 oct. 2019 à 16:17, Markus Karg <ka...@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
> >
> >
> >
>

AW: User Question: Complex Adapters

Posted by Markus Karg <ka...@quipsy.de>.
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)?

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.

Wdyt?

-Markus


-----Ursprüngliche Nachricht-----
Von: Romain Manni-Bucau <rm...@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-performance>


Le mar. 1 oct. 2019 à 16:17, Markus Karg <ka...@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
>
>
>

Re: User Question: Complex Adapters

Posted by Romain Manni-Bucau <rm...@gmail.com>.
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-performance>


Le mar. 1 oct. 2019 à 16:17, Markus Karg <ka...@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
>
>
>