When developing in Ignition, it is often helpful to take a close look at the data types of objects available in jython, whether those types are imports from Java, or a native Jython types, or some exotic wrapper applied to a particular java object for best behavior in Jython.
These script functions are the successor to
shared.inspect.introspect(), a workhorse
written in jython that dates back to 2008 and the FactoryPMI
predecessor to Ignition. (It is still available as
if you need it.)
Certain data types are misleading when reflection is executed purely within jython–this set of functions resolves that difficulty.
Plain Java Reflection
The signature of
object() below triggers generic conversion of
Jython values to Java equivalents, so that reflection occurs with
a native java object where applicable (for the most part).
When jython has wrapped
a generic Java object for the interpreter’s use, this generic
conversion simply yields the original java object, for no surprises.
For native Jython types, you get some subclass of
PyObject as it
appears to native java code. These are rather busy and the output
is long even when
system.reflect.object(javaObject, verbose=False) returns
- Any java object to be examined in detail with reflection.
- A boolean flag to trigger a complete walk of the subject’s java class hierarchy, reporting non-public methods and fields, and where possible, the current (possibly abbreviated) value of those fields.
Coerced Java Reflection
When jython is passing objects as arguments to java methods, it it naively selects a method overload based on number of parameters, then attempts to coerce the supplied arguments to the data types needed by the java method. Some of the coercion decisions are complex, and the plain java introspection above may not correspond to what really happens in specific cases.
If you know a java method’s parameter types, you can have the jython object coerced into the target type just as if it were being handed to that method by the interpreter.
system.reflect.coerced(pyObject, class, verbose=False) returns
- Any jython object that you might supply to a java method and for which you need to examine the coerced form in detail, via reflection.
- A java data type (instance of
Class<?>) that corresponds to the method parameter type. You can use reflection before this call to obtain the correct type.
- A boolean flag to trigger a complete walk of the subject’s java class hierarchy, as coerced, reporting non-public methods and fields, and where possible, the current (possibly abbreviated) value of those fields.
Jython PyObject Reflection
Jython’s own objects’ structure is hidden from jython scripts as implementation details. Some of those implementation details, particularly of wrapper types, may be important. The jython object itself, and its multiple inheritance hierarchy (in method resolution order) can be examined in detail.
system.reflect.pyObject(pyObject, verbose=False) returns
- Any jython object to be examined in detail with reflection.
- A boolean flag to trigger reporting of the current (possibly abbreviated) attribute values.