Custom module fails when ran in tag change script

Hi folks,

Created my first module, which imports some java functions to connect to a mongodB or azure data lake instance. I have an issue with running our module in certain cases. When running the shared script via Script console there are no problems. However, when I try running the same script via Gateway event script-Tag Change it gives me error:

ERROR::shared.datacollector.listServiceOrder.ListGateways:: No module named microsoft

I am taking this means that it cannot access or find our custom module. I am assuming Gateway event script-Tag Change are considered within the gateway scope. And in my module.xml file I do see the line

azure-data-lake-store-sdk-2.2.3.jar

Is it because my hooks/scope is not configured correctly?

Ken

1 Like

If all your module does is load these jars up into various scopes, then what you’re seeing is expected, because your module has its own ClassLoader that is underneath the ClassLoader that gateway scripts are going to be executing in.

Typically to add functionality from 3rd party libraries via a module you do so by adding your own scripting functions to the system, which in turn make use of the library.

The gateway uses a different classloader for each custom module, each separate from the global classloader that is reachable from gateway shared and project scripts. This means that classes in jars supplied by your custom module are usable within all of your java code, but are not importable in any jython scripts.
Your gateway hook can supply a initializeScriptManager() method that injects one of your own classes into the script environment, typically as “system.someModule”, where the class’s methods become functions like “system.someModule.someFunction”. Those java functions should call functions/methods elsewhere in your module that perform any necessary operations with the third-party jar. You can supply documentation for these functions for your users’ convenience in the designer.
A class supplied initializeScriptManager() may also inject aliases for classes from a jar by placing

static public final someClass = com.microsoft.....someClass.class;

That will make someClass available to jython as system.someModule.someClass.
If you absolutely have to make the entire jar available to the global classloader, you can use the < export/ > tag in your module.xml file in place of the < jar/ > tag. You won’t be able to replace that jar by reinstalling your module, though, so only use that technique if you can afford to restart Ignition to update the jar.

Ah ok so I am assuming you are referring to something like this?

Yes, but one of your own classes that has its static methods tailored for maximum compatibility with Ignition. Your own class would call the stuff in the third party jar on jython’s behalf.