# ObjectWrapper Conversion

**URL:** <https://forum.inductiveautomation.com/t/objectwrapper-conversion/64982>\
**Category:** Ignition\
**Tags:** ignition81, perspective\
**Created:** [October 9, 2022, 1:46am UTC](https://forum.inductiveautomation.com/t/objectwrapper-conversion/64982 "2022-10-09T01:46:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [October 9, 2022, 1:46am UTC](https://forum.inductiveautomation.com/t/objectwrapper-conversion/64982/1 "2022-10-09T01:46:51Z")

</div>

Per this comment:

> [@On another topic](https://forum.inductiveautomation.com/t/64538/17):
>
> You might be able to simplify some of those with `JsonUtilities`, fyi: [JsonUtilities](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.20/com/inductiveautomation/ignition/common/JsonUtilities.html)

I am working on a simplified script to convert nested `ObjectWrappers` into pure python objects. I was guessing that maybe [javaToJson](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.20/com/inductiveautomation/ignition/common/JsonUtilities.html#javaToJson(java.lang.Object)) might be the way to do it, but I am getting a malformedJson error.

> **MalformedJson Exception**
>
> ```auto
> com.inductiveautomation.ignition.common.script.JythonExecException
> Traceback (most recent call last):
> File "<function:runAction>", line 6, in runAction
> File "<function:runAction>", line 4, in convertObj
> at com.inductiveautomation.ignition.common.gson.JsonParser.parse(JsonParser.java:65)
> at com.inductiveautomation.ignition.common.gson.JsonParser.parse(JsonParser.java:45)
> at com.inductiveautomation.ignition.common.JsonUtilities.javaToJson(JsonUtilities.java:660)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> at java.base/java.lang.reflect.Method.invoke(Unknown Source)
> com.inductiveautomation.ignition.common.gson.JsonSyntaxException: com.inductiveautomation.ignition.common.gson.JsonSyntaxException: com.inductiveautomation.ignition.common.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 17 path $
> 
> at org.python.core.Py.JavaError(Py.java:547)
> at org.python.core.Py.JavaError(Py.java:538)
> at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:192)
> at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:208)
> at org.python.core.PyObject. __call__ (PyObject.java:461)
> at org.python.core.PyObject. __call__ (PyObject.java:465)
> at org.python.pycode._pyx221.convertObj$2(<function:runAction>:4)
> at org.python.pycode._pyx221.call_function(<function:runAction>)
> at org.python.core.PyTableCode.call(PyTableCode.java:173)
> at org.python.core.PyBaseCode.call(PyBaseCode.java:134)
> at org.python.core.PyFunction. __call__ (PyFunction.java:416)
> at org.python.pycode._pyx221.runAction$1(<function:runAction>:8)
> at org.python.pycode._pyx221.call_function(<function:runAction>)
> at org.python.core.PyTableCode.call(PyTableCode.java:173)
> at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
> at org.python.core.PyFunction.function ___call__ (PyFunction.java:474)
> at org.python.core.PyFunction. __call__ (PyFunction.java:469)
> at org.python.core.PyFunction. __call__ (PyFunction.java:464)
> at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:839)
> at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:821)
> at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:828)
> at com.inductiveautomation.ignition.common.script.ScriptManager$ScriptFunctionImpl.invoke(ScriptManager.java:1002)
> at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.invoke(ProjectScriptLifecycle.java:893)
> at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:147)
> at com.inductiveautomation.perspective.gateway.action.ScriptAction.runAction(ScriptAction.java:74)
> at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.lambda$call$0(ActionCollection.java:263)
> at com.inductiveautomation.perspective.gateway.api.LoggingContext.mdc(LoggingContext.java:54)
> at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:252)
> at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:221)
> at com.inductiveautomation.perspective.gateway.threading.BlockingTaskQueue$TaskWrapper.run(BlockingTaskQueue.java:154)
> at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
> at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
> at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
> at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
> at com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58)
> at java.base/java.lang.Thread.run(Unknown Source)
> Caused by: org.python.core.PyException
> Traceback (most recent call last):
> File "<function:runAction>", line 6, in runAction
> File "<function:runAction>", line 4, in convertObj
> at com.inductiveautomation.ignition.common.gson.JsonParser.parse(JsonParser.java:65)
> at com.inductiveautomation.ignition.common.gson.JsonParser.parse(JsonParser.java:45)
> at com.inductiveautomation.ignition.common.JsonUtilities.javaToJson(JsonUtilities.java:660)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> at java.base/java.lang.reflect.Method.invoke(Unknown Source)
> com.inductiveautomation.ignition.common.gson.JsonSyntaxException: com.inductiveautomation.ignition.common.gson.JsonSyntaxException: com.inductiveautomation.ignition.common.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 17 path $
> 
> ... 36 more
> Caused by: com.inductiveautomation.ignition.common.gson.JsonSyntaxException
> com.inductiveautomation.ignition.common.GenericTransferrableException: com.inductiveautomation.ignition.common.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 17 path $
> at com.inductiveautomation.ignition.common.gson.JsonParser.parse(JsonParser.java:65)
> at com.inductiveautomation.ignition.common.gson.JsonParser.parse(JsonParser.java:45)
> at com.inductiveautomation.ignition.common.JsonUtilities.javaToJson(JsonUtilities.java:660)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> at java.base/java.lang.reflect.Method.invoke(Unknown Source)
> at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:190)
> ... 33 more
> Caused by: com.inductiveautomation.ignition.common.gson.stream.MalformedJsonException
> com.inductiveautomation.ignition.common.GenericTransferrableException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 17 path $
> at com.inductiveautomation.ignition.common.gson.stream.JsonReader.syntaxError(JsonReader.java:1568)
> at com.inductiveautomation.ignition.common.gson.stream.JsonReader.checkLenient(JsonReader.java:1409)
> at com.inductiveautomation.ignition.common.gson.stream.JsonReader.doPeek(JsonReader.java:542)
> at com.inductiveautomation.ignition.common.gson.stream.JsonReader.peek(JsonReader.java:425)
> at com.inductiveautomation.ignition.common.gson.JsonParser.parse(JsonParser.java:60)
> ... 40 more
> 
> Ignition v8.1.18 (b2022061518)
> Java: Azul Systems, Inc. 11.0.15
> 
> ```

Often we need to serialize deeply-nested Perspective properties into Json so that we can store them in a database.

The test object I am trying to convert is:

```auto
{
  "myVar": "value",
  "myNestedObj": {
    "myVal": 1,
    "myArr": [
      "value1",
      "value2"
    ]
  }
}

```

Looking through the above-mentioned [JsonUtilities](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.20/com/inductiveautomation/ignition/common/JsonUtilities.html) class I am not seeing anything obvious.

I appreciate any ideas on how to more affectively convert over these ObjectWrappers!

---

<div class="post-metadata">

**Author:** ![jeremy.lecoutre](https://avatars.discourse-cdn.com/v4/letter/j/3e96dc/32.png) [@jeremy.lecoutre](https://forum.inductiveautomation.com/u/jeremy.lecoutre)\
**Post date:** [October 9, 2022, 2:10pm UTC](https://forum.inductiveautomation.com/t/objectwrapper-conversion/64982/2 "2022-10-09T14:10:18Z")

</div>

you can use system.util.jsonEncode  
[https://docs.inductiveautomation.com/display/DOC81/system.util.jsonEncode](https://docs.inductiveautomation.com/display/DOC81/system.util.jsonEncode)

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 10, 2022, 2:34pm UTC](https://forum.inductiveautomation.com/t/objectwrapper-conversion/64982/3 "2022-10-10T14:34:31Z")

</div>

Most of the JsonUtilities methods expect you to already have a typed gson `JsonElement` instance, since that's how we represent JSON objects in Java code internally.

[TypeUtilities](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.20/com/inductiveautomation/ignition/common/TypeUtilities.html) has `pyToGson` and `gsonToPy` methods that will do the conversion for you.

I mentioned it as an offhand thing; some of the utilities in there aren't going to be super 'idiomatic' to use from Python, but stuff like iterating via a JsonPath is probably nicer to rely on our internal implementation than having to make yourself.
