Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make use of JSR 353 (JSON Processing) API #105

Open
luolong opened this issue Jul 15, 2015 · 12 comments
Open

Make use of JSR 353 (JSON Processing) API #105

luolong opened this issue Jul 15, 2015 · 12 comments
Labels

Comments

@luolong
Copy link

luolong commented Jul 15, 2015

Hey,

I wonder if you are aware of JSR 353 API that is apparently part of JavaEE 7 specification.

Looking around in the source at least I could not see any obvious references to that.

@Langtonm
Copy link

This would be an excellent feature as it is not currently possible to correctly process javax.json.JsonValue items via JsonPath.read.

e.g.

{

    String json = ....;

    System.out.println("Process Raw String (works)");
    System.out.println( JsonPath.read(json, "$.words"));
    System.out.println( JsonPath.read(json, "$.words[*].[?(@.word == 'and')]"));


    System.out.println("Process Json Object (fails due to 'DEBUG com.jayway.jsonpath.Criteria - Can not compare a java.lang.String with a org.glassfish.json.JsonStringImpl)'");
    JsonObject jsonObj = readString(json);

    System.out.println( JsonPath.read(jsonObj, "$.words"));
    System.out.println( JsonPath.read(jsonObj, "$.words[*].[?(@.word == 'and')]"));
}

private static JsonObject readString(String jsonString) {
    if (jsonString == null) {
        return null;
    }
    JsonReader rdr = Json.createReader(new StringReader(jsonString));
    return rdr.readObject();
}

@trajano
Copy link
Contributor

trajano commented Sep 24, 2015

My "inefficient" workaround for now is to call JsonObject.toString() and then parse it using one of the supported providers. I had to do it with a few other libraries including jsonschema2pojo for my project. It would be nice if it can be natively done though.

@kallestenflo
Copy link
Contributor

I had a go at implementing a JavaxJsonProvider based on the Glassfish reference implementation but I ran into some problems with one method.

JsonProvider.setArrayIndex(Object array, int index, Object newValue)

The problem is that the Glassfish JsonArray implementation is immutable and I had to do stuff via reflection. I think it works but I'm not sure if it's the way to go. I'll elaborate some more.

@trajano
Copy link
Contributor

trajano commented Sep 30, 2015

My recommendation is don't. Just let it be known that it is inefficient as the object needs to be rebuilt. I tried mucking around these capabilities before but when you switch to another provider such as web sphere Liberty it can break and you won't have the sources to debug against.

On Wed, Sep 30, 2015 at 1:21 PM, kallestenflo notifications@github.com
wrote:

I had a go at implementing a JavaxJsonProvider based on the Glassfish reference implementation but I ran into some problems with one method.
JsonProvider.setArrayIndex(Object array, int index, Object newValue)

The problem is that the Glassfish JsonArray implementation is immutable and I had to do stuff via reflection. I think it works but I'm not sure if it's the way to go. I'll elaborate some more.

Reply to this email directly or view it on GitHub:
#105 (comment)

@jochenberger
Copy link
Contributor

We could replace void JsonProvider.setArrayIndex(Object array, int index, Object newValue) with Object updateArrayWith(Object array, int index, Object newValue). and void setProperty(final Object obj, final Object key, final Object value) with Object updateObjectWith(final Object obj, final Object key, final Object value). That would make it easier to work with immutable data structures.
If we say that it's okay to modify the argument, some implementations could do that for efficiency reasons, but we could also decide that a new Object is to be returned by all implementations.

@jochenberger
Copy link
Contributor

I think that a decision should be made here. If we want to change the JSONProvider interface, 3.0.0 might be a good time to do it.

@jbaiter
Copy link

jbaiter commented Feb 8, 2017

Any update on this?

@TuomasKiviaho
Copy link

There came an upgrade to that JSR 374: JavaTM API for JSON Processing 1.1 a while ago but the older one is supported for Jackson either partially via https://github.com/FasterXML/jackson-datatype-jsr353 or fully via https://github.com/pgelinas/jackson-javax-json so that the project isn't stuck just with the RI

@bram209
Copy link

bram209 commented May 31, 2019

Any update?

@greek1979
Copy link
Contributor

greek1979 commented Jun 14, 2021

Just joining the party... As I had to work with Jakarta EE 9 specifications for JSON processing (and dynamic data binding), there is a support for both JSON-P and JSOB-B in their latest reincarnations in PR #734 .

However, the issue of immutability of both the Json objects (JsonObject) and arrays (JsonArray) is plaguing me, too. Not sure there is a good way around this. Reflection (as explained above) is a strong "no" due to possibly different implementations out there.

Returning a different object / array every time there is a set(), add() or delete() operation on it? Seems straightforward from API point of view, both JSON-P and JsonPath (if its API or at least the documentation for it are updated accordingly). But there is a bigger catch... As JSON-P essentially builds a DOM-like tree of JSON objects, arrays, and plain values, changing a "child object" deep down the tree means we still have a tree with AN OLD OBJECT, and the NEW OBJECT with our data existing outside the tree. Moreover, if modified object's parent is itself a child of another JSON object, then THAT "grand-pa" object has to be replaced in the tree hierarchy, too. And so on all the way to the root ( $ ) object, or array. This can be done, of course, but at what performance / computational cost?

Ref: https://stackoverflow.com/a/62167824/3627515

Note to myself: the above is actually a fundamental issue with JSON-P specification itself, not JsonPath library. It wasn't simply designed with "in place" modifications and amendments in mind; it was crafted around "read and parse once, build and write once" concept.

@greek1979
Copy link
Contributor

Replying to myself. Within the same pull request #734, I have added the recursive proxying behavior for JSON objects and array returned by the JSON-P implementation (whatever it is), so objects that are formally immutable by the spec, would appear to JsonPath internal code as fully mutable. Any changes done by JsonPath classes are effectively proxied into respective calls to JSON-P builders, replacing underlying (proxied) object or array accordingly, while hiding this fact from JsonPath caller. This approach does not feel very nice from purely JSON-P 1.1 strict compliance perspective, but it allows to retain all the JsonPath existing codebase and functionality - while working with different Jakarta EE 9 JSON-P implementations without breaking them. JSON-B compliancy is also fully supported.

@greek1979
Copy link
Contributor

greek1979 commented May 23, 2022

With JsonPath v2.7.0 release, support for Jakarta JSON API (JSON-P and JSON-B) is there, and I'd suggest to close this issue. More information about Jakarta EE JSON API support is in #734.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants