users@jsonb-spec.java.net

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

From: Martin Vojtek <voytoo_at_gmail.com>
Date: Fri, 6 Mar 2015 06:52:23 +0100

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