users@jsonb-spec.java.net

[jsonb-spec users] Re: [jsr367-experts] Re: Re: [2-DefaultMapping] Proposal

From: Eugen Cepoi <cepoi.eugen_at_gmail.com>
Date: Fri, 6 Mar 2015 00:54:48 -0800

Hey Martin,

Yes it is planned to support any json value as root element
https://java.net/jira/browse/JSON_PROCESSING_SPEC-65

But anyway, from what I see of the api now, it should not be an issue as it
is more impl related. Still the examples can exhibit it, but that's not so
important. I guess end users will not look at them...

Cheers,
Eugen
Le 5 mars 2015 21:53, "Martin Vojtek" <voytoo_at_gmail.com> a écrit :

> Hi Eugen,
>
> is JSR 374 going to support any json values as root element? In that case
> JSON Binding should aso support it.
>
> Martin
>
> On Thu, Mar 5, 2015 at 11:14 PM, Eugen Cepoi <cepoi.eugen_at_gmail.com>
> wrote:
>
>>
>>
>> 2015-03-05 12:31 GMT-08:00 Martin Vojtek <voytoo_at_gmail.com>:
>>
>>> Hi Olena and Kiev UA JUG,
>>>
>>> thank you very much for your feedback.
>>>
>>> ad 1)
>>>
>>> there are several specifications related to JSON and they are not
>>> consistent in the definition of JSON.
>>>
>>> According to RF4627 (http://www.ietf.org/rfc/rfc4627.txt):
>>>
>>> A JSON text is a serialized object or array.
>>>
>>> There are also several online JSON validators, which supports the idea,
>>> e.g. http://jsonlint.com/
>>> There are also several JSON validators, which are supporting all JSON
>>> values, not only object or array.
>>>
>>> On the other hand, there is also newer proposed standard RFC 7159, which
>>> relaxes this https://datatracker.ietf.org/doc/rfc7159
>>>
>>> A JSON text is a sequence of tokens. The set of tokens includes six
>>> structural characters, strings, numbers, and three literal names.
>>>
>>> A JSON text is a serialized value. Note that certain previous
>>> specifications of JSON constrained a JSON text to be an object or an
>>>
>>> array. Implementations that generate only objects or arrays where a
>>> JSON text is called for will be interoperable in the sense that all
>>> implementations will accept these as conforming JSON texts.
>>>
>>> I have to confess, that my first non-public proposal was accepting also
>>> JSON values.
>>>
>>
>> And you were right IMO :)
>>
>>
>>>
>>> I see the following advantages supporting only objects and arrays as
>>> JSON text:
>>>
>>> 1. JSR 353: JavaTM API for JSON Processing (
>>> https://jcp.org/en/jsr/detail?id=353)
>>> JsonReader and JsonParser support only objects and arrays.
>>>
>>
>> Not the next update. The new JSR will also support any json values as
>> root element.
>>
>>
>>>
>>> JsonReader jsonReader = Json.createReader(new StringReader("1"));
>>> System.out.println(jsonReader.read()); //javax.json.JsonException: Empty
>>> stream
>>>
>>> There is no event emitted:
>>> JsonParser parser = Json.createParser(new StringReader("1"));
>>> while (parser.hasNext()) {
>>> JsonParser.Event event = parser.next();
>>> System.out.println("event="+event); //never happens
>>> }
>>>
>>> JSON Binding should be compatible with JSR 353, and it is expected, that
>>> JSON Binding RI will use JSON Processing RI.
>>>
>>> 2. Interoperability as stated in RFC 7159
>>>
>>> 3. I don't see much value added supporting this use case
>>>
>>>
>> Maybe allowing to ser/de a root null object...or a root byte array ser/de
>> using base64 encoded string.
>> But I don't see either a reason to restrict it.
>>
>>
>>> *I definitely want to hear some other opinions on this topic. *
>>>
>>> ad 2)
>>>
>>> It is clear that escaping must be supported. I will add some explicit
>>> examples to express this.
>>>
>>> ad 3)
>>>
>>> The intention of these examples was to express, that default
>>> implementation of Map should be LinkedHashMap<String, Object>.
>>> Key/value pairs in JSON objects are not ordered, but it is very
>>> practical to have these pairs ordered.
>>>
>>> From my point of view, the most reasonable implementation for JSON array
>>> is ArrayList<Object>.
>>>
>>> If I specify default implementation for JSON object, it makes sense to
>>> specify also default implementation for JSON array (at least for
>>> consistency).
>>>
>>> Other advantage is predictability from the user of this API. If we don't
>>> specify this, this will be probably implemented differently by different
>>> implementations.
>>> I can imagine that different fields could have different implementations
>>> like Arrays.asList(...), Collections.EMPTY_LIST and so on.
>>> This can be problematic in some use cases.
>>> Specifying default implementations (for default mapping) will improve
>>> operability and provide some sensible defaults for the user of the API.
>>>
>>>
>> *I definitely want to hear some other opinions on this topic too. *
>>>
>>> MartinV
>>>
>>>
>>> On Thu, Mar 5, 2015 at 5:58 PM, Olena Syrota <sirotae_at_gmail.com> wrote:
>>>
>>>> Hi guys,
>>>>
>>>> More feedback from Kiev UA JUG (with Oleg Tsal-Tsalko and Andrii
>>>> Rodionov).
>>>>
>>>> 1. JSON value formatting. Let me propose to follow The JSON Data
>>>> Interchange Format (
>>>> http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
>>>> Due to this document JSON value is printed without square brackets "[...]".
>>>> Square brakets are used for JSON array.
>>>>
>>>> e.g.
>>>>
>>>> - jsonb.fromJson("1", Byte.class)
>>>>
>>>> instead of
>>>>
>>>> - jsonb.fromJson("[1]", Byte.class), etc.
>>>>
>>>>
>>>> 2. More cases for String mapping should be considered. Due to
>>>> http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf,
>>>> page 5, we should add mapping cases for \", /, \\, \r, \n, \t, \f, \b,
>>>> \uXXXX.
>>>> See
>>>> https://github.com/sirotae/jsonb-spec-ua-adopt/tree/master/examples/src/test/java/jug/ua/jsonb/examples/default_mapping,
>>>> file StringMapping.java
>>>>
>>>> 3. Structure Mapping from Json.
>>>> Case 1. Instead of
>>>>
>>>> - Collection<Object> collection =
>>>> (ArrayList<Object>)jsonb.fromJson("[{\"value\":\"first\"},
>>>> {\"value\":\"second\"}]", Object.class);
>>>>
>>>>
>>>> Let me propose:
>>>>
>>>> - List<Object> act = (List)jsonb.fromJson("[{\"value\":\"first\"},
>>>> {\"value\":\"second\"}]", Object.class);
>>>>
>>>>
>>>> Case 2. Instead of
>>>>
>>>> - Map<String, Object> map =
>>>> (LinkedHashMap<String,Object>)jsonb.fromJson("{\"name\":\"unknown
>>>> object\"}", Object.class);
>>>>
>>>>
>>>> let me propose
>>>>
>>>> - Map<String, Object> map =
>>>> (Map)jsonb.fromJson("{\"name\":\"unknown object\"}", Object.class);
>>>>
>>>>
>>>>
>>>> Thank you
>>>> Olena
>>>>
>>>> 2015-03-04 0:05 GMT+02:00 Eugen Cepoi <cepoi.eugen_at_gmail.com>:
>>>>
>>>>> The way byte arrays are being ser/de can be a config. option.
>>>>> The advantage of base64 is that it produces much smaller json than
>>>>> using an array.
>>>>> I didn't benchmark ser/de speed when using one or the other but I
>>>>> guess the difference is probably not so big.
>>>>>
>>>>> Eugen
>>>>>
>>>>> 2015-03-03 13:47 GMT-08:00 Hendrik Dev <hendrikdev22_at_gmail.com>:
>>>>>
>>>>> Hi all,
>>>>>>
>>>>>> what about byte[] serialization and deserialization to/from base64?
>>>>>> For me its natural (like proposed by MartinV) so ser/deser into a
>>>>>> array of bytes like [3,-1,33,-11] but some json binding frameworks out
>>>>>> there ser/deser byte[] to/from a base64 encoded string by default.
>>>>>> To make the spec compatible with them maybe we should consider to
>>>>>> support both?
>>>>>>
>>>>>> Wdyt?
>>>>>>
>>>>>> Thanks
>>>>>> Hendrik
>>>>>>
>>>>>>
>>>>>> On Fri, Feb 27, 2015 at 5:45 PM, Martin Grebac <
>>>>>> martin.grebac_at_oracle.com> wrote:
>>>>>> >
>>>>>> > Please ignore the last point - bad example. Will provide multiple
>>>>>> examples
>>>>>> > within the generics topic.
>>>>>> > MartiNG
>>>>>> >
>>>>>> >
>>>>>> > On 27.02.15 10:03, Martin Grebac wrote:
>>>>>> >>
>>>>>> >> On 25.02.15 20:29, Przemyslaw Bielicki wrote:
>>>>>> >>>
>>>>>> >>>
>>>>>> >>> Yes exactly like this.
>>>>>> >>>
>>>>>> >> Not sure exactly like what - are you suggesting both scenarios?
>>>>>> Root level
>>>>>> >> as well as nested?
>>>>>> >>
>>>>>> >>> Without typetoken it could be difficult as Optional is a final
>>>>>> class thus
>>>>>> >>> we cannot make custom classes like OptionalFoo extends
>>>>>> Optional<Foo>
>>>>>> >>>
>>>>>> >>> 25 lut 2015 19:35 "Eugen Cepoi" <cepoi.eugen_at_gmail.com
>>>>>> >>> <mailto:cepoi.eugen_at_gmail.com>> napisał(a):
>>>>>> >>>
>>>>>> >>> If it is about Optional at the mapping level I am not sure
>>>>>> there
>>>>>> >>> is a need to make it appear in the spec.
>>>>>> >>>
>>>>>> >> In spec we have to define (or decide to not to define) the
>>>>>> behaviour for
>>>>>> >> Optional within default mapping at least to not cause portability
>>>>>> problems.
>>>>>> >>
>>>>>> >>> The use case I would see with optional at root level is when
>>>>>> the
>>>>>> >>> root value it self is null... with typetoken could look like
>>>>>> (I
>>>>>> >>> don't know how you plan to handle generics):
>>>>>> >>>
>>>>>> >>> Optional<Foo> optFoo = jsonb.fromJson(json, new
>>>>>> >>> TypeToken<Optional<Foo>>() {})
>>>>>> >>>
>>>>>> >> What is the value that this support brings to JSON Binding? Does
>>>>>> this have
>>>>>> >> value for further work with optFoo?
>>>>>> >> The call requires constructing the specific type, requires us to
>>>>>> remove
>>>>>> >> type checking from the method signature which is useful in
>>>>>> non-generic
>>>>>> >> cases, and I'm not sure about the value or problem it actually
>>>>>> solves.
>>>>>> >>
>>>>>> >>> But the most common would be to have optional nested in Pojo
>>>>>> like
>>>>>> >>> structures. In that case it would be handled directly by
>>>>>> impls.
>>>>>> >>>
>>>>>> >> We're again inherently discussing generics here with Optional,
>>>>>> too. And
>>>>>> >> the same as above applies - we need portable behaviour. So, let's
>>>>>> say we
>>>>>> >> have
>>>>>> >>
>>>>>> >> public class B {
>>>>>> >> Optional<C> c;
>>>>>> >> }
>>>>>> >> public class C {
>>>>>> >> Optional<List<Optional<String>>> s;
>>>>>> >> OptionalInt i;
>>>>>> >> D<String,Long> d;
>>>>>> >> }
>>>>>> >> public class D<T1,T2> {
>>>>>> >> List<T1> l1;
>>>>>> >> Optional<T2> t2;
>>>>>> >> }
>>>>>> >>
>>>>>> >> And you want to be marshalling / unmarshalling from / into this
>>>>>> structure.
>>>>>> >> How would the implementation at runtime be able to defer and
>>>>>> create proper
>>>>>> >> types for the individual properties?
>>>>>> >>
>>>>>> >> MartiNG
>>>>>> >>
>>>>>> >>> 2015-02-25 5:27 GMT-08:00 Martin Grebac <
>>>>>> martin.grebac_at_oracle.com
>>>>>> >>> <mailto:martin.grebac_at_oracle.com>>:
>>>>>> >>>
>>>>>> >>> On 25.02.15 8:44, Przemyslaw Bielicki wrote:
>>>>>> >>>
>>>>>> >>> The trouble with Optional is that it is typed,
>>>>>> and as
>>>>>> >>> such its use is too complex within the api
>>>>>> methods we
>>>>>> >>> have now compared to the minimal benefit it
>>>>>> brings.
>>>>>> >>>
>>>>>> >>> Anyway I think it should be impl specific feature -
>>>>>> sorry
>>>>>> >>> for the noise.
>>>>>> >>>
>>>>>> >>> After re-reading I think I may have been too fast and
>>>>>> >>> misunderstood the usecase. Before I jump into my rant on
>>>>>> >>> Optional :) , would you please give some examples of the
>>>>>> >>> expected outcomes, say based on MartinV's default mapping
>>>>>> >>> examples?
>>>>>> >>>
>>>>>> >>> I think it makes sense to get some clarity into this and
>>>>>> make
>>>>>> >>> decisions whether the support for Optional should be in
>>>>>> the
>>>>>> >>> spec, whether it should be default, and whether it should
>>>>>> be
>>>>>> >>> spec defined configuration, mostly because Optional has
>>>>>> value
>>>>>> >>> wrt lambdas. Thus I also expect the reasoning will likely
>>>>>> have
>>>>>> >>> to include the expected stream use? I don't find Optional
>>>>>> >>> bringing any significant value outside of streams.
>>>>>> >>>
>>>>>> >>> MartiNG
>>>>>> >>>
>>>>>> >
>>>>>> > --
>>>>>> > Martin Grebac, SW Engineering Manager
>>>>>> > Oracle Czech, Prague
>>>>>> >
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Hendrik Saly (salyh, hendrikdev22)
>>>>>> @hendrikdev22
>>>>>> PGP: 0x22D7F6EC
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>