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: Thu, 5 Mar 2015 14:14:57 -0800

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