I'm trying to use a java library in Ignition to manipulate MQTT messages through protobuf.
The library is called tahu: https://github.com/eclipse/tahu/tree/master/java.
I was able to build it without problems following the instructions:
When I copy the generated ".jar" file to "Ignition\lib\core\common"...
...the "MQTT Engine" module stops working because this error occurs:
There seems to be a dependency conflict.
Any help please?
The MQTT modules use Tahu internally (their own copy) and you have overridden with a likely-incompatible version.
You have three choices:
Java classloader trickery to access Cirrus Link's packaged tahu, or
Package your jar in a module so it gets its own isolated classloader, then expose selected classes/methods with Ignition's ScriptManager infrastructure, or
Create a simple module that depends on an MQTT module, then expose selected classes/methods from the Cirrus Link tahu with Ignition's ScriptManager infrastructure.
(None of those are trivial, sorry. Start with Ignition's SDK examples.)
Thanks for the response.
Regarding the first option, what does "Java classloader trickery" mean? Do you mean this object: ClassLoader (Java Platform SE 8 )? Is there any example or documentation of how to access a class packaged inside a module (".modl")?
MQTT Engine Module contains Tahu.Core.1.0.5.jar and Tahu.Host.1.0.5.jar
Both export their main classes, look at their manifest:
So, really this classes should be used from gateways scripts.
I've taken the simple example from Tahu:
And I've succesfully imported all the classes used by the example in a script of the project library. Look as the execution on the Script Console does not return any error after impoting all the classes used by the example.
Try to tanslate the rest of the java example to jython, I think it should work.
No, in the Gateway, modules are loaded in their own isolated ClassLoader. Scripting does not have access to the JARs used by modules in Gateway scope.
It works in the Designer console because Cirrus Link is also loading these JARs in Client/Designer scope, and in Client/Designer scope there is no module ClassLoader hierarchy like in the Gateway.
You are right.
So, recovering the comment from "pturmel" (Java classloader trickery to access Cirrus Link's packaged tahu ...).Do you think It's possible to work in the gateway scope trough the Cirrus Gateway Module Hook ? How could I obtain information of the classes exposed by the Cirrus Gateway Module Hook?
Given a gateway context or module context in gateway scope (such as provided by
system.util.toolkitCtx() in my
Integration Toolkit), you can uses its
.getModule() method to obtain the hook class instance. That class will have a dedicated module classloader that is responsible for the module's jars. You can ask that classloader to load classes by name for you. Once you have a class loaded into a name in a jython interpreter, it behaves just like an imported class.
It will take a time to implement a working example, but, by the moment I could instantiate a SparkplugB Payload Builder:
hook = system.util.toolkitCtx().getModule('com.cirruslink.mqtt.engine.gateway').getClass()
cloader = java.lang.Class.getClassLoader(hook)
_SparkplugBPayload = cloader.loadClass('org.eclipse.tahu.message.model.SparkplugBPayload')
deathPayload = _SparkplugBPayload.SparkplugBPayloadBuilder()