[JSONP-24] Sequence of adding a JsonArrayBuilder into a JsonObjectBuilder interferes in the final result Created: 27/Oct/13  Updated: 27/Oct/13

Status: Open
Project: jsonp
Component/s: None
Affects Version/s: 1.0.3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Hildeberto Mendonça Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

JDK 1.7, Glassfish 3.1.2.2, Jersey 1.8


Tags: JsonArrayBuilder, JsonObject, JsonObjectBuilder

 Description   

While creating some Json content using the Object Model API, I realised that the sequence of adding a JsonArrayBuilder into a JsonObjectBuilder interferes in the final result. The following code won't include the categories in the resulting Json because the line, indicated with an arrow, adds the JsonArrayBuilder to the JsonObjectBuilder before JsonArrayBuilder is loaded with data :

List<CategoryMenu> categories = categoryMenuBean.findCategoriesByMenu(menu);
JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
JsonArrayBuilder arrayBuilderCategories = Json.createArrayBuilder();

objectBuilder.add("categories", arrayBuilderCategories); // <--

for(CategoryMenu category: categories) {
     arrayBuilderCategories.add(Json.createObjectBuilder()
                 .add("id", category.getId())
                 .add("name", category.getName()));
}

JsonObject model = objectBuilder.build();
StringWriter strWriter = new StringWriter();
try (JsonWriter jsonWriter = Json.createWriter(strWriter)) {
     jsonWriter.writeObject(model);
}

System.out.println(strWriter.toString()); // output = []

To work around with the problem, I had to move that highlighted line to after the iteration:

List<CategoryMenu> categories = categoryMenuBean.findCategoriesByMenu(menu);
JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
JsonArrayBuilder arrayBuilderCategories = Json.createArrayBuilder();

for(CategoryMenu category: categories) {
     arrayBuilderCategories.add(Json.createObjectBuilder()
                 .add("id", category.getId())
                 .add("name", category.getName()));
}

objectBuilder.add("categories", arrayBuilderCategories); // <--

JsonObject model = objectBuilder.build();
StringWriter strWriter = new StringWriter();
try (JsonWriter jsonWriter = Json.createWriter(strWriter)) {
     jsonWriter.writeObject(model);
}
System.out.println(strWriter.toString()); // output = {"categories":[{"id":1,"name":"Plat du Jour"},{"id":2,"name":"Permanent"}]}

Apparently, the build is performed right away, while data is added to those builder objects. In fact, it should be built only when the method build() is finally invoked. In both examples, it always happen when all data is added to the builders and it is time to build the final JsonObject model. Therefore, both examples above should work normally.






[JSONP-32] Doubt about writeEscapedString() Created: 08/May/16  Updated: 05/Jul/16

Status: Open
Project: jsonp
Component/s: None
Affects Version/s: 1.0.4
Fix Version/s: None

Type: Bug Priority: Major
Reporter: j4nbur53 Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

All



 Description   

There are some doubts about writeEscapedString(). This method
char c = s.charAt; but then at some place it compares c < 0x10FFFF.

But this test trivially always true since char data type is in the range
0x0000 to 0xFFFF. Is the intention of the code to use s.codePointAt()?



 Comments   
Comment by j4nbur53 [ 08/May/16 ]

Given that a Java String uses surrogate pairs for ranges above 0xFFFF, the code
somehow does what it should do, since the escaped codes 0x00-0x1F, 0x22 and 0x5c
are anyway in the lowest Unicode plane, not needing surrogate pairs.

Comment by Robin479 [ 04/Jul/16 ]

There is another subtle error near those lines: the character U+007F ("delete") and the character range U+0080 through U+009F ("C1 control codes") are control characters, which require escaping according to the JSON specification. The solution might be to escape JSON special characters U+0022 and U+005C (and optionally, U+002F), as well as characters for which java.lang.Character.isISOControl() is true.

Additionally, most JavaScript clients (erroneously) require the escaping of ALL line-terminating characters, which includes characters of the type java.lang.Character#LINE_SEPARATOR (currently only U+2028) and java.lang.Character#PARAGRAPH_SEPARATOR (currently only U+2029). Since JSON allows optional escaping of any character, the escaping of these problematic types of characters would be appreciated (see java.lang.Character.getType()).

Here's a replacement for writeEscapedString() which does all that:

    void writeEscapedString(String string) {
        writeChar('"');
        int b = 0, len = string.length(); // b =: start of to-be-written characters (buffer)
        for (int i = b; i < len; i++) {
            final char c = string.charAt(i);
            if (c == '"' || c == '\\' || c == '/') {
                writeString(string, b, i); b = i+1; // flush/reset buffer
                writeChar('\\'); writeChar(c); // escape JSON special character
            } else if (c < ' ' || '~' < c) { // (outside printable ASCII range)
                switch (Character.getType(c)) {
                    case Character.CONTROL:
                        final int idx = "\n\r\t\f\b".indexOf(c);
                        if (0 <= idx) {
                            writeString(string, b, i); b = i+1; // flush/reset buffer
                            writeChar('\\'); writeChar("nrtfb".charAt(idx)); // escape well-known controls
                            break; // from switch
                        } // else: fall through
                    case Character.LINE_SEPARATOR: // most JavaScript consumers require escaping...
                    case Character.PARAGRAPH_SEPARATOR:  // ...of ALL line-terminating characters
                        writeString(string, b, i); b = i+1; // flush/reset buffer
                        final String hex = Integer.toHexString(c);
                        writeString("\\u0000", 0, 6 - hex.length());
                        writeString(hex);
                }
            }
        }
        writeString(string, b, len); // flush buffer
        writeChar('"');
    }




[JSONP-29] JsonPaser#getString() returns wrong value Created: 09/Jun/15  Updated: 26/Sep/16

Status: Open
Project: jsonp
Component/s: None
Affects Version/s: 1.0.4
Fix Version/s: None

Type: Bug Priority: Major
Reporter: jspiegel Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

JDK7



 Description   

The reference implementation fails to raise an error when the input JSON is invalid. Here is a reproducer:

JsonParser parser = Json.createParser(new StringReader("{\"a\":13"));
parser.next(); // START_OBJECT
parser.next(); // KEY_NAME
parser.next(); // VALUE_NUMBER
System.out.println(parser.getString()); // "13a":1



 Comments   
Comment by ren.zhijun.oracle [ 23/Sep/16 ]

I tested with 1.1.0-SNAPSHOT implementation, and the output is (is this your expected):

13,

not:

"13a":1

Comment by jspiegel [ 23/Sep/16 ]

I assume you mean the result is "13" and not "13,"?

13 would be acceptable as long as an additional call to parser.next() raises a parse error since the input is missing the final right curly bracket.

Comment by ren.zhijun.oracle [ 26/Sep/16 ]

Yes, the out put is 13

and an extra parser.next() throw exception like:
Exception in thread "main" java.util.NoSuchElementException
at org.glassfish.json.JsonParserImpl.next(JsonParserImpl.java:351)
at Jsonp29.main(Jsonp29.java:12)

So I will close the bug, do you agree?

Comment by jspiegel [ 26/Sep/16 ]

It should raise JsonParsingException with a message that is helpful to the user.

https://json-processing-spec.java.net/nonav/releases/1.0/pfd-draft/javadocs/javax/json/stream/JsonParser.html#next()
Throws:
JsonParsingException - if the parser encounters invalid JSON when advancing to next state.

Most parsers would give a message like "Unexpected end of input. Expected '}' or ','" Or something like this. And ideally this message would include the line and column where the error was encountered.





[JSONP-27] Using OSGi cannot load the service Created: 19/Sep/14  Updated: 19/Sep/14

Status: Open
Project: jsonp
Component/s: None
Affects Version/s: 1.0.4
Fix Version/s: None

Type: Bug Priority: Major
Reporter: bakos.gabor Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

OSGi (4.x)



 Description   

I was trying to use the jsonp project as a default implementation for the json-api in an OSGi environment (eclipse 3.7), although the ServiceLoader is not quite OSGi-friendly solution, so no services found for JsonProvider#provider() and because the JsonProvider from the javax.json-api (1.0) was also loaded if I use that JsonProvider from that bundle (that is loaded first, so most probably this happens) it cannot find the default implementation either.
As a workaround we had to use a different (from the javax.json-api bundle, the one of org.glassfish.javax.json) ContextClassLoader for the thread calling the JsonProvider#provider() method and add a service reference to the jsonp bundle (so it can find that service with the provided classloader).
Ideally the would be to make loading the services load in OSGi environments (that would be the goal of the spi-fly project, but unfortunately that is not an option for us yet, it requires OSGi R5 or above, be we have to support eclipse 3.7 for a while), though for us, currently the exposed service would be sufficient with the workaround.
Could you add a service reference to the default implementation or give other satisfying solution that make this plugin work in OSGi R4 environments?






[JSONP-1] JSON not getting deserialized in a WebSocket endpoint Created: 24/Oct/12  Updated: 24/Oct/12

Status: Open
Project: jsonp
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: arungupta Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

@Override
public MyMessage decode(String string) throws DecodeException

{ System.out.println("decoding: " + string); this.jsonObject = new JsonReader(new StringReader(string)).readObject(); System.out.println(jsonObject); return this; }

is throwing the following exception:

INFO: decoding: { }
SEVERE: javax.json.JsonException: Provider org.glassfish.json.JsonProviderImpl not found
at javax.json.spi.JsonProvider.provider(JsonProvider.java:101)
at javax.json.Json.createParser(Json.java:84)
at org.glassfish.jsonapi.JsonReaderImpl.<init>(JsonReaderImpl.java:58)
at javax.json.JsonReader.<init>(JsonReader.java:77)
at org.sample.MyMessage.decode(MyMessage.java:60)
at org.sample.MyMessage.decode(MyMessage.java:53)
at org.glassfish.tyrus.platform.WebSocketEndpointImpl.decodeMessage(WebSocketEndpointImpl.java:212)
at org.glassfish.tyrus.platform.WebSocketEndpointImpl.processMessage(WebSocketEndpointImpl.java:315)
at org.glassfish.tyrus.platform.WebSocketEndpointImpl.onMessage(WebSocketEndpointImpl.java:300)
at org.glassfish.tyrus.spi.grizzlyprovider.GrizzlyEndpoint.onMessage(GrizzlyEndpoint.java:82)
at org.glassfish.grizzly.websockets.DefaultWebSocket.onMessage(DefaultWebSocket.java:164)
at org.glassfish.grizzly.websockets.frametypes.TextFrameType.respond(TextFrameType.java:70)
at org.glassfish.grizzly.websockets.DataFrame.respond(DataFrame.java:104)
at org.glassfish.grizzly.websockets.WebSocketFilter.handleRead(WebSocketFilter.java:221)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:265)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:134)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:825)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:578)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:558)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.ClassNotFoundException: org.glassfish.json.JsonProviderImpl not found by org.glassfish.main.web.core [246]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1460)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at javax.json.spi.JsonProvider.provider(JsonProvider.java:96)
... 27 more

SEVERE: at javax.json.spi.JsonProvider.provider(JsonProvider.java:101)
SEVERE: at javax.json.Json.createParser(Json.java:84)
SEVERE: at org.glassfish.jsonapi.JsonReaderImpl.<init>(JsonReaderImpl.java:58)
SEVERE: at javax.json.JsonReader.<init>(JsonReader.java:77)
SEVERE: at org.sample.MyMessage.decode(MyMessage.java:60)
SEVERE: at org.sample.MyMessage.decode(MyMessage.java:53)
SEVERE: at org.glassfish.tyrus.platform.WebSocketEndpointImpl.decodeMessage(WebSocketEndpointImpl.java:212)
SEVERE: at org.glassfish.tyrus.platform.WebSocketEndpointImpl.processMessage(WebSocketEndpointImpl.java:315)
SEVERE: at org.glassfish.tyrus.platform.WebSocketEndpointImpl.onMessage(WebSocketEndpointImpl.java:300)
SEVERE: at org.glassfish.tyrus.spi.grizzlyprovider.GrizzlyEndpoint.onMessage(GrizzlyEndpoint.java:82)
SEVERE: at org.glassfish.grizzly.websockets.DefaultWebSocket.onMessage(DefaultWebSocket.java:164)
SEVERE: at org.glassfish.grizzly.websockets.frametypes.TextFrameType.respond(TextFrameType.java:70)
SEVERE: at org.glassfish.grizzly.websockets.DataFrame.respond(DataFrame.java:104)
SEVERE: at org.glassfish.grizzly.websockets.WebSocketFilter.handleRead(WebSocketFilter.java:221)
SEVERE: at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
SEVERE: at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:265)
SEVERE: at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
SEVERE: at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:134)
SEVERE: at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
SEVERE: at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
SEVERE: at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:825)
SEVERE: at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
SEVERE: at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
SEVERE: at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
SEVERE: at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
SEVERE: at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:578)
SEVERE: at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:558)
SEVERE: at java.lang.Thread.run(Thread.java:722)
SEVERE: Caused by: java.lang.ClassNotFoundException: org.glassfish.json.JsonProviderImpl not found by org.glassfish.main.web.core [246]
SEVERE: at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1460)
SEVERE: at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72)
SEVERE: at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
SEVERE: at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
SEVERE: at javax.json.spi.JsonProvider.provider(JsonProvider.java:96)
SEVERE: ... 27 more






[JSONP-38] adding a containsValue method into the JsonPointer class Created: 18/Jan/17  Updated: 18/Jan/17

Status: Open
Project: jsonp
Component/s: None
Affects Version/s: 1.1.0
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: ozlerhakan Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hi all,

It would be good If the JsonPointer class has a containsValue method like:

public boolean containsValue(JsonStructure target)

So that, this ability lets us control whether the specified value exists on the target JSON document without getting an exception directly.

Wdyt?






[JSONP-39] Provide APIs to create JsonValue out of primitives Created: 19/Jan/17  Updated: 19/Jan/17

Status: Open
Project: jsonp
Component/s: None
Affects Version/s: 1.1.0
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: jaikiran.pai Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

As noted in the mail[1] in the user mailing list, right now there's no straightforward way to create JsonValue out of primitive types. For example there's no way currently (via the spec APIs) to create a JsonString out of a java.lang.String such that the escaping and other details are taken care by the API implementation itself without me as a user having to come up with custom implementations to deal with the escaping and even creating a custom class that implements JsonString.

Same applies to other primitive types like integers, double and numbers in general for which I don't currently have a spec API which will return me a JsonNumber for them. The mail referenced in this JIRA has a bit more details about what would be good to have APIs.

[1] https://java.net/projects/json-processing-spec/lists/users/archive/2015-12/message/26






[JSONP-40] Missing geNumber method in JsonNumber Created: 20/Jan/17  Updated: 20/Jan/17

Status: Open
Project: jsonp
Component/s: None
Affects Version/s: 1.1.0
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Tomas Kraus Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I need to pass content of JsonNumber to BSONObject as it is, without taking care what specific Number type is stored in it.






Generated at Mon Jan 23 01:39:58 UTC 2017 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.