ralfstx / minimal-json

A fast and small JSON parser and writer for Java
MIT License
732 stars 186 forks source link

Deadlock during Json / JsonValue class initialization #88

Open sbernard31 opened 6 years ago

sbernard31 commented 6 years ago

I face some deadlock during JUnit tests of my maven build. Some time ago, I was using v0.9.4 and deadlock was always reproducible. Since v0.9.5 and #77, I face it only sporadically.

Here is a thread dump when tests are stucked with v0.9.5 ``` "pool-1-thread-11" #21 daemon prio=5 os_prio=0 tid=0x00007ff840403000 nid=0x16da in Object.wait() [0x00007ff80eb4f000] java.lang.Thread.State: RUNNABLE at com.eclipsesource.json.Json.(Json.java:63) at org.eclipse.leshan.json.ObjectModelSerDesTest.des_ser_must_be_equals(ObjectModelSerDesTest.java:49) 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:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at org.apache.maven.surefire.junitcore.pc.InvokerStrategy.schedule(InvokerStrategy.java:54) at org.apache.maven.surefire.junitcore.pc.Scheduler.schedule(Scheduler.java:346) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.junit.runners.Suite.runChild(Suite.java:127) at org.junit.runners.Suite.runChild(Suite.java:26) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - <0x000000076dd38ca0> (a java.util.concurrent.ThreadPoolExecutor$Worker) "pool-1-thread-10" #20 daemon prio=5 os_prio=0 tid=0x00007ff840401000 nid=0x16d9 in Object.wait() [0x00007ff80ec50000] java.lang.Thread.State: RUNNABLE at org.eclipse.leshan.json.LwM2mJson.fromJsonLwM2m(LwM2mJson.java:34) at org.eclipse.leshan.json.JsonDeserializerTest.deserialize_device_object(JsonDeserializerTest.java:52) 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:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at org.apache.maven.surefire.junitcore.pc.InvokerStrategy.schedule(InvokerStrategy.java:54) at org.apache.maven.surefire.junitcore.pc.Scheduler.schedule(Scheduler.java:346) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.junit.runners.Suite.runChild(Suite.java:127) at org.junit.runners.Suite.runChild(Suite.java:26) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - <0x000000076dd38910> (a java.util.concurrent.ThreadPoolExecutor$Worker) "pool-1-thread-9" #19 daemon prio=5 os_prio=0 tid=0x00007ff8403ff000 nid=0x16d8 in Object.wait() [0x00007ff80ed51000] java.lang.Thread.State: RUNNABLE at com.eclipsesource.json.JsonValue.(JsonValue.java:71) at org.eclipse.leshan.json.JsonRootObjectSerDes.jSerialize(JsonRootObjectSerDes.java:30) at org.eclipse.leshan.json.JsonRootObjectSerDes.jSerialize(JsonRootObjectSerDes.java:24) at org.eclipse.leshan.core.model.json.JsonSerDes.sSerialize(JsonSerDes.java:31) at org.eclipse.leshan.json.LwM2mJson.toJsonLwM2m(LwM2mJson.java:30) at org.eclipse.leshan.json.JsonSerializerTest.serialize_device_object(JsonSerializerTest.java:97) 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:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at org.apache.maven.surefire.junitcore.pc.InvokerStrategy.schedule(InvokerStrategy.java:54) at org.apache.maven.surefire.junitcore.pc.Scheduler.schedule(Scheduler.java:346) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.junit.runners.Suite.runChild(Suite.java:127) at org.junit.runners.Suite.runChild(Suite.java:26) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - <0x000000076dd38580> (a java.util.concurrent.ThreadPoolExecutor$Worker) "pool-1-thread-4" #14 daemon prio=5 os_prio=0 tid=0x00007ff8403f5000 nid=0x16d3 in Object.wait() [0x00007ff80f256000] java.lang.Thread.State: RUNNABLE at org.eclipse.leshan.json.LwM2mJson.fromJsonLwM2m(LwM2mJson.java:34) at org.eclipse.leshan.core.node.codec.json.LwM2mNodeJsonDecoder.decode(LwM2mNodeJsonDecoder.java:59) at org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder.decode(DefaultLwM2mNodeDecoder.java:72) at org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder.decode(DefaultLwM2mNodeDecoder.java:46) at org.eclipse.leshan.core.node.codec.LwM2mNodeDecoderTest.json_device_object_instance0_with_root_basename(LwM2mNodeDecoderTest.java:448) 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:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at org.apache.maven.surefire.junitcore.pc.InvokerStrategy.schedule(InvokerStrategy.java:54) at org.apache.maven.surefire.junitcore.pc.Scheduler.schedule(Scheduler.java:346) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.junit.runners.Suite.runChild(Suite.java:127) at org.junit.runners.Suite.runChild(Suite.java:26) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - <0x000000076dd37360> (a java.util.concurrent.ThreadPoolExecutor$Worker) "pool-1-thread-2" #12 daemon prio=5 os_prio=0 tid=0x00007ff8403f1800 nid=0x16d1 in Object.wait() [0x00007ff80f458000] java.lang.Thread.State: RUNNABLE at org.eclipse.leshan.json.JsonRootObjectSerDes.jSerialize(JsonRootObjectSerDes.java:30) at org.eclipse.leshan.json.JsonRootObjectSerDes.jSerialize(JsonRootObjectSerDes.java:24) at org.eclipse.leshan.core.model.json.JsonSerDes.sSerialize(JsonSerDes.java:31) at org.eclipse.leshan.json.LwM2mJson.toJsonLwM2m(LwM2mJson.java:30) at org.eclipse.leshan.core.node.codec.json.LwM2mNodeJsonEncoder.encodeTimestampedData(LwM2mNodeJsonEncoder.java:86) at org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder.encodeTimestampedData(DefaultLwM2mNodeEncoder.java:94) at org.eclipse.leshan.core.node.codec.LwM2mNodeEncoderTest.json_encode_timestamped_resources(LwM2mNodeEncoderTest.java:211) 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:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at org.apache.maven.surefire.junitcore.pc.InvokerStrategy.schedule(InvokerStrategy.java:54) at org.apache.maven.surefire.junitcore.pc.Scheduler.schedule(Scheduler.java:346) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.junit.runners.Suite.runChild(Suite.java:127) at org.junit.runners.Suite.runChild(Suite.java:26) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:387) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - <0x000000076dd36c10> (a java.util.concurrent.ThreadPoolExecutor$Worker) ```
pstanton commented 4 years ago

Correct me, but this sounds easy to fix and it's not been fixed just to provide backwards compatibility? for over a year?

If so, I will begin using another library.

sbernard31 commented 4 years ago

I still face this issue sporadically... This is pretty annoying :confused:
Any chance to get a fix this ?

@pstanton to you still face this issue ?

bernardosulzbach commented 4 years ago

This project is mostly unmaintained, as far as I know. I would suggest either forking it or migrating to a new JSON dependency if this is giving you problems.

Don't get me wrong: I also really liked this library, but sometimes OSS just gets abandoned.

sbernard31 commented 3 years ago

Just to let you know we finally switch to Jackson.

bernardosulzbach commented 3 years ago

@sbernard31 can you tell me on which JVMs (versions too) you were able to reproduce this problem?

sbernard31 commented 3 years ago

Hard question as this was a long time ago. If I remember correctly OpenJDK 7 and 8 I guess. I'm not able to give you more precise information. :disappointed:

bernardosulzbach commented 3 years ago

IIRC I convinced myself at some point that this was a JDK issue, as the apparent race condition seemed to be fine according to the language specification. I have a strong impression that I never saw it on Oracle JDKs.

pstanton commented 3 years ago

you might be right - i've reproduced using OpenJDK Runtime Environment (build 1.8.0_232-8u232-b09-1~deb9u1-b09)

however the issue is easily fixed and i patched our copy of this lib before moving away from it since. nfi why that wasn't just done years ago.

bernardosulzbach commented 3 years ago

I don't think it could have been patched in any way without breaking existing code. That, combined with the slow death of the project, is why I think this wasn't and will never be fixed.

Regarding moving on from this project: I'd say existing users should either fork (possibly still as OSS, as there may be more people interested) or go for something that is actively maintained. Nobody should at this point add a dependency to this project.

pstanton commented 3 years ago

ok, i can't disagree however i would have thought a major version update would have been fine. it is ok to have non-backwards-compatible changes occasionally - especially if it is to solve critical issues such as this.

tobiasbaum commented 1 year ago

If anybody is still interested in this: I took the PR from pstanton (https://github.com/ralfstx/minimal-json/pull/115), created a version 1.0.0 for it and published a binary in a new fork: https://github.com/tobiasbaum/minimal-json/releases/tag/v1.0.0

If anybody knows how to publish this to Maven Central, I'd be happy to know.