JsonIOException in system.net.httpClient

Hmm. Has anyone run into this one?

com.inductiveautomation.ignition.common.gson.JsonIOException: Failed making field 'java.lang.ref.Reference#referent' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.
	at com.inductiveautomation.ignition.common.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:38)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:286)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
	at com.inductiveautomation.ignition.common.gson.Gson.getAdapter(Gson.java:556)
	at com.inductiveautomation.ignition.common.gson.internal.bind.CollectionTypeAdapterFactory.create(CollectionTypeAdapterFactory.java:53)
	at com.inductiveautomation.ignition.common.gson.Gson.getAdapter(Gson.java:556)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
	at com.inductiveautomation.ignition.common.gson.Gson.getAdapter(Gson.java:556)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
	at com.inductiveautomation.ignition.common.gson.Gson.getAdapter(Gson.java:556)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:45)
	at com.inductiveautomation.ignition.common.gson.Gson.getAdapter(Gson.java:556)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
	at com.inductiveautomation.ignition.common.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
	at com.inductiveautomation.ignition.common.gson.Gson.getAdapter(Gson.java:556)
	at com.inductiveautomation.ignition.common.gson.Gson.toJson(Gson.java:834)
	at com.inductiveautomation.ignition.common.gson.Gson.toJsonTree(Gson.java:712)
	at com.inductiveautomation.ignition.common.gson.Gson.toJsonTree(Gson.java:689)
	at com.inductiveautomation.ignition.common.TypeUtilities.pyToGson(TypeUtilities.java:2068)
	at com.inductiveautomation.ignition.common.TypeUtilities.pyToGson(TypeUtilities.java:2050)
	at com.inductiveautomation.ignition.common.script.builtin.http.JythonHttpClient.lambda$buildRequest$7(JythonHttpClient.java:234)
	at java.base/java.util.Optional.ifPresentOrElse(Unknown Source)
	at com.inductiveautomation.ignition.common.script.builtin.http.JythonHttpClient.buildRequest(JythonHttpClient.java:198)
	at com.inductiveautomation.ignition.common.script.builtin.http.JythonHttpClient.post(JythonHttpClient.java:320)
	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)
	at org.python.core.PyObject.__call__(PyObject.java:422)
	at org.python.core.PyMethod.instancemethod___call__(PyMethod.java:237)
	at org.python.core.PyMethod.__call__(PyMethod.java:228)
	at org.python.pycode._pyx8.apiPost$5(<module:licensing>:52)
	at org.python.pycode._pyx8.call_function(<module:licensing>)
	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 org.python.core.PyObject._callextra(PyObject.java:589)
	at org.python.pycode._pyx9.callAsyncInvoked$16(<module:later>:173)
	at org.python.pycode._pyx9.call_function(<module:later>)
	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:847)
	at com.inductiveautomation.ignition.client.script.DesignerSystemUtilities.lambda$_invokeAsyncImpl$1(DesignerSystemUtilities.java:140)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.Object java.lang.ref.Reference.referent accessible: module java.base does not "opens java.lang.ref" to unnamed module @31fe31d4
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(Unknown Source)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(Unknown Source)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Unknown Source)
	at java.base/java.lang.reflect.Field.setAccessible(Unknown Source)
	at com.inductiveautomation.ignition.common.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:35)
	... 54 common frames omitted

Calling .post() on an httpClient shared instance.

Ignition v8.1.38.

Just upgraded this instance from v8.1.28 to a get away from a PMITextArea bug. :frowning_face:

What data are you posting?

Your upgrade has moved you from JDK 11 to JDK 17.

It seems you're posting something that has an object that GSON was once able to reflectively serialize but now cannot because JDK 17 stopped allowing illegal reflection access without the explicit --add-opens for that package.

1 Like

I was letting httpClient turn a simple dictionary into json.

Further debugging with system.util.jsonEncode() gave me a stack overflow.

I've since found a code typo that put a non-string entry in that dictionary. (Jython's built-in license?) Still investigating.

Jython's json.dumps gave my the type error that led to the typo.

Will report more when I understand what was/is happening.

Yeah, I expected that. And I cleared the .ignition/cache for this target. Surprised that a system function could trigger this reflection error.

Meh, this system function accepts arbitrary user data and tries to serialize it into JSON.

My gateway ignition.conf has these:

wrapper.java.additional.16=--add-opens=java.base/java.lang=ALL-UNNAMED
wrapper.java.additional.17=--add-opens=java.base/java.security.cert=ALL-UNNAMED
wrapper.java.additional.18=--add-opens=java.base/java.util=ALL-UNNAMED
wrapper.java.additional.19=--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED
wrapper.java.additional.20=--add-opens=java.base/java.io=ALL-UNNAMED

Does the gateway hand such off to the designer and to Vision clients?

You may still need another line for java.lang.ref...

I don't think so, but I also don't see any by default in the Designer Launcher, and I thought there was some place these were defined... @jcoffman whatcha say?

Ok, so it looks like Client/Designer get them from the launch manifest, but still haven't tracked down where those values come from...

Ahhhh, $IGNITION/lib/runtime/client-exports.conf and client-opens.conf.

also, fwiw, the client-exports.conf and client-opens.conf files in lib/runtime are owned and updated by IA, so the next bump to Ignition will result it your changes being discarded.

You can augment these files with your own files at data/client-opens.conf and data/client-exports.conf files.

so in this case add a file data/client-opens.conf which has the line

java.base/java.lang.ref

This will be preserved across upgrades and be present for all new client and designer launches.

1 Like

A non string key?

Would definitely be good to know the actual type/data.

I left this out of my post because there's a nice comment at the top of our files that explains this.

1 Like

Well. Seems license is a magic keyword in jython. Try this:

def testLicenseEncode():
	payload = {'somekey': 'someValue', 'license_key': license}
	print type(license)
	print system.util.jsonEncode(payload, 2)

testLicenseEncode()

Kaboom!

I'll let you all figure this one out.

<class 'site._Printer'>

:hmm:

in site.py:

class _Printer(object):
    """interactive prompt objects for printing the license text, a list of
    contributors and the copyright notice."""

:hmmmmmmmmm:

1 Like

Yeah, site.py has this:

def setcopyright():
    # ...
    __builtin__.license = _Printer(
        "license", "See http://www.python.org/%.3s/license.html" % sys.version,
        ["LICENSE.txt", "LICENSE"],
        [os.path.join(here, os.pardir), here, os.curdir])

which is called in a method called main which is called at the top level of that file :person_shrugging:

2 Likes