mmastrac / nanojson Goto Github PK
View Code? Open in Web Editor NEWA tiny, compliant JSON parser and writer for Java
Home Page: https://github.com/mmastrac/nanojson
A tiny, compliant JSON parser and writer for Java
Home Page: https://github.com/mmastrac/nanojson
Main article: http://seriot.ch/parsing_json.html
Results for nanojson: http://seriot.ch/json/parsing.html#20
The 1.1 release needs to be pushed out to Maven. We also need to submit a patch to JSONTestSuite to use 1.1.
I haven't had much time to work on the library recently, but I've merged my JsonReader
branch in and the codebase is in good shape. If anyone is interested in taking over, please let me know.
If you're going to use jmods and jlink, an automatic module name is not sufficient as the java module dependencies are lacking.
I have a jdk11 version to solve this, coming soon.
So it appears that non-finite numbers produce invalid JSON, as far as I can tell. For example, the following round trip crashes:
String json = JsonWriter.string().value(Double.NaN).done();
JsonReader.from(json).doubleVal();
The reason is that the produced JSON is simply NaN
. I think it should be "NaN"
- this is at least what Jackson does. Either that, or the parser should be able to read unquoted non-finite values.
Not a blocker for me, but I thought you would want to know.
public static String getSteemitRequest(String method, Object[] params) {
JsonStringWriter steemitRequestsWriter = JsonWriter.string().object();
steemitRequestsWriter.value(Words.ID, getId());
steemitRequestsWriter.value(Words.JSONRPC, Versions.SECOND_ONE_DOT);
steemitRequestsWriter.value(Words.METHOD, method);
steemitRequestsWriter.value(Words.PARAMS, params);
return steemitRequestsWriter.done();
}
...
getSteemitRequest("get_content", "@sempervideo/mq3ykiml".split("/"));
got me this Exception:
com.grack.nanojson.JsonWriterException: Unclosed JSON objects and/or arrays when closing writer
at com.grack.nanojson.JsonWriterBase.doneInternal(Unknown Source)
at com.grack.nanojson.JsonStringWriter.done(Unknown Source)
Why ?
I tried to build your nanojson project (downloaded master on 2014-05-27) using the command on your README page ("mvn clean compile test jar:jar"). However, it failed some of the unit tests and halted the build.
My build computer is Windows 8.1 (x64) with JDK8 (x64, build 5) and Apache Maven 3.2.1
Below is the output of running "mvn clean compile test jar:jar" :
[INFO] Scanning for projects...
[INFO]
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building nanojson 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ nanojson ---
[INFO] Deleting C:\Users\CCHall\Downloads\nanojson-master\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ nanojson ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\Users\CCHall\Downloads\nanojson-master\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ nanojson ---
[INFO] Compiling 13 source files to C:\Users\CCHall\Downloads\nanojson-master\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ nanojson ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\Users\CCHall\Downloads\nanojson-master\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ nanojson ---
[INFO] Compiling 1 source file to C:\Users\CCHall\Downloads\nanojson-master\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ nanojson ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 3 resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ nanojson ---
[INFO] Compiling 5 source files to C:\Users\CCHall\Downloads\nanojson-master\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ nanojson ---
[INFO] Surefire report directory: C:\Users\CCHall\Downloads\nanojson-master\target\surefire-reports
Running com.grack.nanojson.JsonNumberTest
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.093 sec
Running com.grack.nanojson.JsonParserTest
Tests run: 62, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.194 sec <<< FAILURE!
testObjectWithEverything(com.grack.nanojson.JsonParserTest) Time elapsed: 0.007 sec <<< FAILURE!
org.junit.ComparisonFailure: expected:<{[jkl=null, abc=123, ghi=[true, false], def=456.0], mno=true}> but was:<{[abc=123, def=456.0, ghi=[true, false], jkl=null], mno=true}>
at org.junit.Assert.assertEquals(Assert.java:124)
at org.junit.Assert.assertEquals(Assert.java:146)
at com.grack.nanojson.JsonParserTest.testObjectWithEverything(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:44)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
testObjectTwoElements(com.grack.nanojson.JsonParserTest) Time elapsed: 0.002 sec <<< FAILURE!
org.junit.ComparisonFailure: expected:<{[B=1, a]=1}> but was:<{[a=1, B]=1}>
at org.junit.Assert.assertEquals(Assert.java:124)
at org.junit.Assert.assertEquals(Assert.java:146)
at com.grack.nanojson.JsonParserTest.testObjectTwoElements(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:44)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Running com.grack.nanojson.JsonTypesTest
Tests run: 12, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.01 sec <<< FAILURE!
testJsonArrayBuilder(com.grack.nanojson.JsonTypesTest) Time elapsed: 0 sec <<< FAILURE!
org.junit.ComparisonFailure: expected:<...,[1,null],[1,2,3],{"[b":null,"c":null,"a]":null}]> but was:<...,[1,null],[1,2,3],{"[a":null,"b":null,"c]":null}]>
at org.junit.Assert.assertEquals(Assert.java:124)
at org.junit.Assert.assertEquals(Assert.java:146)
at com.grack.nanojson.JsonTypesTest.testJsonArrayBuilder(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:44)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
testJsonObjectBuilder(com.grack.nanojson.JsonTypesTest) Time elapsed: 0.003 sec <<< FAILURE!
org.junit.ComparisonFailure: expected:<{"b[igint":1234567890,"int":1,"string":"hi","existingObject":{"b":null,"c":null,"a":null},"existingArray":[1,2,3],"object":{"abc":123},"bool":true,"double":1.0,"float":1.0,"null":null,"array":[1,null]]}> but was:<{"b[ool":true,"string":"hi","null":null,"existingArray":[1,2,3],"array":[1,null],"double":1.0,"float":1.0,"existingObject":{"a":null,"b":null,"c":null},"bigint":1234567890,"int":1,"object":{"abc":123}]}>
at org.junit.Assert.assertEquals(Assert.java:124)
at org.junit.Assert.assertEquals(Assert.java:146)
at com.grack.nanojson.JsonTypesTest.testJsonObjectBuilder(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:44)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Running com.grack.nanojson.JsonWriterTest
Tests run: 35, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.065 sec <<< FAILURE!
testObjectArrayInMap(com.grack.nanojson.JsonWriterTest) Time elapsed: 0 sec <<< FAILURE!
org.junit.ComparisonFailure: expected:<{"array of [JsonObject":[{},null],"array of Boolean":[true,false]],"array of string":...> but was:<{"array of [Boolean":[true,false],"array of JsonObject":[{},null]],"array of string":...>
at org.junit.Assert.assertEquals(Assert.java:124)
at org.junit.Assert.assertEquals(Assert.java:146)
at com.grack.nanojson.JsonWriterTest.testObjectArrayInMap(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:44)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Results :
Failed tests: testObjectWithEverything(com.grack.nanojson.JsonParserTest): expected:<{[jkl=null, abc=123, ghi=[true, false], def=456.0], mno=true}> but was:<{[abc=123, def=456.0, ghi=[true, false], jkl=null], mno=true}>
testObjectTwoElements(com.grack.nanojson.JsonParserTest): expected:<{[B=1, a]=1}> but was:<{[a=1, B]=1}>
testJsonArrayBuilder(com.grack.nanojson.JsonTypesTest): expected:<...,[1,null],[1,2,3],{"[b":null,"c":null,"a]":null}]> but was:<...,[1,null],[1,2,3],{"[a":null,"b":null,"c]":null}]>
testJsonObjectBuilder(com.grack.nanojson.JsonTypesTest): expected:<{"b[igint":1234567890,"int":1,"string":"hi","existingObject":{"b":null,"c":null,"a":null},"existingArray":[1,2,3],"object":{"abc":123},"bool":true,"double":1.0,"float":1.0,"null":null,"array":[1,null]]}> but was:<{"b[ool":true,"string":"hi","null":null,"existingArray":[1,2,3],"array":[1,null],"double":1.0,"float":1.0,"existingObject":{"a":null,"b":null,"c":null},"bigint":1234567890,"int":1,"object":{"abc":123}]}>
testObjectArrayInMap(com.grack.nanojson.JsonWriterTest): expected:<{"array of [JsonObject":[{},null],"array of Boolean":[true,false]],"array of string":...> but was:<{"array of [Boolean":[true,false],"array of JsonObject":[{},null]],"array of string":...>
Tests run: 119, Failures: 5, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.045 s
[INFO] Finished at: 2014-05-27T15:12:12-05:00
[INFO] Final Memory: 25M/92M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project nanojson: There are test failures.
[ERROR]
[ERROR] Please refer to C:\Users\CCHall\Downloads\nanojson-master\target\surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
I was looking for a json parser/formatter which can format JSON without normalizing numbers. It could be useful for test frameworks where we want to format json to make it human readable but with a minimum of other changes. For example, trailing decimal places would be preserved.
I thought maybe nanojson with lazy numbers could do that.
@Test
public void testTrailingDecimalLazy() throws JsonParserException {
Object value = JsonParser.any().withLazyNumbers().from("1.000");
String json = JsonWriter.string().value(value).done();
assertEquals("1.000", json);
}
Unfortunately, lazy numbers do not work with JsonWriter. Rather than "1.000", I get "com.grack.nanojson.JsonLazyNumber@18bf3d14". Seems toString() method is missing in JsonLazyNumber.
Is this intentional or accidental? If accidental, can it be added?
Would be nice if you could contribute to the https://github.com/fabienrenaud/java-json-benchmark so thatthe nanojson can be compared with other parsers.
Hi there,
would you be open to somehow exposing the preValue(java.lang.String)
method of JsonWriterBase
? The context is the following:
Suppose that you wanted to split up serialization of your objects into multiple methods that can be reused. Let's say you have classes A
and B
:
class A {
B b;
// ...
}
class B {
int c;
}
If I wanted to extract serialization of B
into its own method, I'd have to write something like:
void writeA(A a, JsonSink sink) {
sink.object();
sink.object("b");
writeB(sink);
sink.end();
sink.end();
}
void writeB(B b, JsonSink sink) {
sink.value("c", b.c);
}
I need to provide a value when specifying a field name, so I need to write the object marker of B
outside of writeB
. This means that writeB
cannot be used as a standalone method. What would fix that is exposing the preValue
method, e.g. through a field
method:
void writeA(A a, JsonSink sink) {
sink.object()
sink.field("b");
writeB(sink);
sink.end();
}
void writeB(B b, JsonSink sink) {
sink.object()
sink.value("c", b.c)
sink.end();
}
Cheers
Please consider adding Automatic-Module-Name to the manifest file, This should be easily handled within Maven. This won't force use of Java 9+, but improve ease of use with it.
This would result in a number of simplified code paths (where you could use getOrDefault, standard charsets, etc.). I'm even tempted to say switch directly to Java 11 as the minimum but since it's such a compact, self-contained project Java 8 seems like a reasonable switch?
Just FYI. The custom handling of UTF8 in JsonTokener is impressive but made me wonder how much is actually there to gain (compared to a buffered reader over a decoding stream). I made a quick wall-time repeated check parsing a contiguous json (with majority in plain ascii but containing some more complex multibyte sequences). The input file is ~350MB and fits entirely in I/O caches.
After a small JVM warmup of a few rounds, the results stabilized around:
internal utf8-decoder: ~1.57 seconds
JDK's utf8-decoder (reader): ~2.00 seconds
So the gain is there but really tiny considering that you typically also do something to the result (and this dominates raw parsing).
I get an ArrayIndexOutOfBoundsException when trying to parse this JSON.
This is kind of a "gotcha" type issue but I think my reasoning is sound.
nanojson parses Java character literals correctly (and goes to great
lengths to make sure the UTF-8 is valid) in the consumeTokenStringUtf8Char
method. But when the characters are escaped (not Java character literals)
it uses the following simplified logic:
int escaped = 0;
for (int i = 0; i < 4; i++) {
escaped <<= 4;
int digit = buffer[index++];
if (digit >= '0' && digit <= '9') {
escaped |= (digit - '0');
} else if (digit >= 'A' && digit <= 'F') {
escaped |= (digit - 'A') + 10;
} else if (digit >= 'a' && digit <= 'f') {
escaped |= (digit - 'a') + 10;
} else {
throw createParseException(null, "Expected unicode hex escape character: " +
(char) digit + " (" + digit + ")", false);
}
}
reusableBuffer.append((char) escaped);
which is not sufficient because there are illegal combinations of encoded
Unicode characters (as well as illegal single characters) which I will now attempt
to show/describe.
The JSON spec states that any character may be escaped. The method
to escape characters outside of the Basic Multilingual Plane (U+0000
through U+FFFF) is as follows:
`To escape an extended character that is not in the Basic Multilingual
Plane, the character is represented as a 12-character sequence,
encoding the UTF-16 surrogate pair. So, for example, a string
containing only the G clef character (U+1D11E) may be represented as
"\uD834\uDD1E".
In other words, characters above U+FFFF are encoded as surrogate pairs.
Thus, the following JSON: "\uD800\uDC00" should decode to the Unicode
character: U+10000.
The following JSON Strings:
1.) "\uD800"
2.) "\uD800\uCC00"
Should fail parsing because a high surrogate character (U+D800) is:
in 1.) not followed by another Unicode character
in 2.) not followed by a low surrogate character
In other words, the following tests should not fail:
@Test
public void testFailBustedString8() {
try {
// High-surrogate character not followed by another Unicode character
JsonParser.any().from("\"\\uD800\"");
fail();
} catch (JsonParserException e) {
testException(e, 1, 7); // 7 may be the wrong char, but is irrelevant for the issue
}
}
@Test
public void testFailBustedString9() {
try {
// High-surrogate character not followed by a low-surrogate character
JsonParser.any().from("\"\\uD800\\uCC00\"");
fail();
} catch (JsonParserException e) {
testException(e, 1, 7); // 7 may be the wrong char, but is irrelevant for the issue
}
}
Thanks for your time, let me know if anything is not clear.
Using nanojson to parse untrusted JSON String may be vulnerable to denial of service (DOS) attacks. If the parser is running on user supplied input, an attacker may supply content that causes the parser to crash by stackoverflow.
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.lang.AbstractStringBuilder.setLength(AbstractStringBuilder.java:274)
at java.base/java.lang.StringBuilder.setLength(StringBuilder.java:90)
at com.grack.nanojson.JsonTokener.consumeTokenString(Unknown Source)
at com.grack.nanojson.JsonTokener.advanceToToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
at com.grack.nanojson.JsonParser.advanceToken(Unknown Source)
<dependency>
<groupId>com.grack</groupId>
<artifactId>nanojson</artifactId>
<version>1.8</version>
</dependency>
import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonParserException;
/**
* JsonFuzzer
*
* @since 1.0.0
*/
public class JsonFuzzer {
public final static int TOO_DEEP_NESTING = 9999;
public final static String TOO_DEEP_Array = _nestedDoc(TOO_DEEP_NESTING, "[ ", "] ", "1");
public final static String TOO_DEEP_Object = "{" + _nestedDoc(TOO_DEEP_NESTING, "\"a\": { ", "} ", "1") + "}";
public static String _nestedDoc(int nesting, String open, String close, String content) {
StringBuilder sb = new StringBuilder(nesting * (open.length() + close.length()));
for (int i = 0; i < nesting; ++i) {
sb.append(open);
if ((i & 31) == 0) {
sb.append("\n");
}
}
sb.append("\n").append(content).append("\n");
for (int i = 0; i < nesting; ++i) {
sb.append(close);
if ((i & 31) == 0) {
sb.append("\n");
}
}
return sb.toString();
}
public static void main(String[] args) {
try {
JsonParser.object().from(TOO_DEEP_Object);
JsonParser.array().from(TOO_DEEP_Array);
} catch (JsonParserException e) {
throw new RuntimeException(e);
}
}
}
Refer to the solution of jackson-databind: Add the depth variable to record the current parsing depth. If the parsing depth exceeds a certain threshold, an exception is thrown. (FasterXML/jackson-databind@fcfc499)
Refer to the GSON solution: Change the recursive processing on deeply nested arrays or JSON objects to stack+iteration processing.((google/gson@2d01d6a20f39881c692977564c1ea591d9f39027))
just a byte array mode that returns byte[]
that can be used as body in http(-s) requests and most other socket connections
Per conversation with @dweiss in another issue, we should probably have a reader mode where exceptions are more readily thrown for things like type cast exceptions.
Hello,
Unlike other java.lang.Number classes, com.grack.nanojson.JsonLazyNumber does not implement toString(), which poses a problem when serializing back to JSON a Java object obtained by parsing its JSON form.
Example: parse "[1,2.0,3.14]" as a JsonArray and serialize it back using JsonWriter.string(Object) and you'll get something like "[com.grack.nanojson.JsonLazyNumber@HHH,com.grack.nanojson.JsonLazyNumber@HHH,com.grack.nanojson.JsonLazyNumber@HHH]".
This is the only problem I found after using nanojson for more than a year. I like it very much: tiny, stable, reliable, documented, no dependencies. We currently use it in XMLmind XML Editor, a commercial product.
Thank you very much for your great software component!
PS: A non-essential feature request. JsonWriter.string(Object) and its likes could support generating indented strings. Not for production use of course, but useful when testing and debugging.
Great project, @mmastrac - thank you for sharing it. I eyeballed the code and have a few minor nitpicks that I can file as a PR if you're interested. One major change that I made locally is to make JsonObject extend LinkedHashMap instead of HashMap. This allows deserialized objects to retain key ordering which is sometimes useful. What do you think?
is it possible to get the length of an JsonArray?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.