Add .JAR for using classes in Jython scripts

Hello!

I started playing with ignition some weeks ago and I would like to use in python some classes/methods from java libraries that are not included in the standard libraries. (i.e. vectorz, poi-ooxml…)

What is the best way to do this?

I’ve been reading the SDK programmers guide and started learning about Java and maven. I’ve installed eclipse, maven, build a module from the gateway-designer-client archetype, configured the hooks with "import " and added to the pom.xml files the libs/versions as dependencies.

After packaging the module (correctly -apparently-, with some .jar and .pack.jar.gz files that maven considers necessary inside the .modl) and signing, I can upload it to my gateway and it shows as “Running”, but I still can’t use the libraries in the playground.

Couldn’t see an example of this in the ignition-sdk-examples. Is this the way to go? Is there another way to use java libraries in python without using a module?

Thanks!
Regards!

If you’re trying to use these libraries in the script playground you have to make sure your module loads them in the appropriate scope(s).

For access in scripting you probably want to load them into all 3 scopes (C, D, G).

Hello Kevin, thanks for the answer.

When you say “your module loads them in the appropriate scope(s)” you mean import them in the 3 hook classes or there’s more to be done?

You just need an empty hook class for each scope, to make sure each scope depends on the jar(s) you’re trying to import, and to make sure the module.xml declares the dependency on the jar in all 3 scopes and has all 3 hooks specified.

Hello!

Thanks Kevin for your responses. I’ve managed to make it work in the designer & client. No luck in the gateway :frowning:.

Libraries are not being loaded in the gateway, when called I get errors (no class found). Libs seems OK (gateway scripts work when libs are placed in the libs folder manually).

I’m working on reading microsoft files and I’ve found Apache Poi is already one of the libs by default in the gateway (but looks like its not complete O_o), anyways I’m trying to load with my module an older version. As I said, this went OK in D and C.

Any idea? :stuck_out_tongue:

Thanks.

Ah, yeah. It’s not going to work with regular dependencies in the gateway because of how modules are loaded in their own ClassLoader.

There’s one trick you can use, but your module won’t be able reloadable/restartable if you do this. In your module.xml, instead of using the ‘jar’ element for the gateway scope, use ‘export’:

    <export scope="G">name-of-jar.jar</export>

Ignition will load this jar in a ClassLoader further up in the hierarchy and it should be available to scripting this way…

Kevin, is there a way to get the <export> tag to be included in the module.xml via the Maven build? I’m trying to find where I can configure that in the build pom, but not having any luck. Thanks!

Kevin, is there a way to get the tag to be included in the module.xml via the Maven build? I'm trying to find where I can configure that in the build pom, but not having any luck. Thanks!

The export functionality is not part of the supported/documented public api, so it's not currently supported in the module plugin. The functionality does present some limitations/potential issues around gw stability, so I am not sure we want to support its wide use.

1 Like

Cool, I can appreciate that… At least now I know it isn’t just something I’m not aware of… I think for my purposes I can wrap the required functionality so I don’t need to expose libraries at the root level… Thanks!

Ant to the rescue! But yeah, don't do it. You can make a script module with static public final Class<?> variables set to the .class elements you wish to expose. Much safer, and gives your user short names for those classes.

1 Like

Hi Kevin,

I am using the pubnub jar file in my gateway scripts on script playground. I took a short cut and just copied the pubnub jar file in lib/core/gateway folder. For Ignition 7.9.10 it works fine immediately after copying the jar. However for Ignition version 8.0, it didn't work! I had to restart the Ignition gateway then it started working! Why in Ignition 8 it requires a restart of gateway? Restart is undesirable as it will interrupt a running gateway server ! How can I avoid it? By writing an empty gateway hook that references (imports) the one of the libraries in the jar? Is there any other simpler way without having to build and install an Ignition module?

Hi @PRAMANJ, I’m curious how you achieved this.
I’m also testing on a 7.9.10 install and was unable to import the Logger.class as a test.
I tried dropping pubnub-3.4.jar into the lib/core/common directory. When I ran from com.pubnub.api import Logger in the script console I got ImportError: No module named pubnub

I’m trying to learn more about these areas of Ignition so any insight would be greatly appreciated.
My end goal would be to achieve exactly what the OP wanted to do with regards to poi-ooxml-4.1.0.jar.
My idea is to get this jar working as you described, then trying to build a module for it.

I was able to get this to work.

I used pack200 to create a pack.gz and placed the jar and the pack.gz files in the lib/core/common.
I restarted the gateway and my designer and I was able to run from com.pubnub.api import Logger without any errors.

Thanks to @Kevin.Herron in this post: Adding java custom classes to Ignition

NOTE* his disclaimer about official support and the SDK is the way to go.

I placed my jars in gateway scope and I was able to access thru gateway scripts in 7.9.10. However for version 8, I too had to restart the gateway and designer once for it to work.
Are you using these jars from modules or from scripts?

Of course sdk is the recommended way but a dreaded the whole process of building empty modules and keeping versions of it for each version of Ignition. So I took the shortcut and it worked (atleast for 7.9.10)

Then don't build empty modules. Put the jars you are deploying into the modules like they're supposed to be, with a script class that exposes the import objects from the jars in the Ignition system.* namespace. You should do the work to make it easy on your potential customers. Don't make them responsible for placing jars in the right places. They might not have convenient filesystem access, but be able to use the module install page in the gateway.

2 Likes

But I don't have any modules ! I simply have jython scripts in gateway that use the libraries from this jar! If at all I have to build a module in gateway scope, then I have to use the skeleton gateway module that's auto generated by maven archetypes for Ignition, and import some functions from these jars without using any of them it it and build the module! That's what I meant by empty module. I hope my point is clear, or I am missing something?

Not clear! I am including an import statement in the skeleton module which uses some of the functions from this jar. Hope that's what you mean? I am actually not using any function in the code of the module.

I guess I will have to eventually make such an empty module and try to Install in Ignition as a regular module which will install the jars in appropriate directories. The biggest advantage besides users convenience is that they can be installed in gateway without having to restart it!

Scripts. I'm working my way to building a module for it so users can use the system.* namespace in there scripts.

My end goal is to expose the apache poi 4.1.0 to end users. I've been digging around the forums and I'm wondering if my end goal is not possible? Kevin mentions a weird corner case about possible conflicts with the reporting module because it uses poi-3.14.

I'm looking for a kick start in the right direction (Uninstalling the reporting module isn't an option for our client); is 4.1.0 not a good idea because of the reporting module? Is it a safer bet to use the same version as the reporting module? Is it possible to just access the existing POI library from all scopes?

Yes, you'll have to use the same version as Reporting.

Only if your module adds it to all scopes. It's added to C/D by Reporting, not gateway.

1 Like

How come import org.apache.poi fails to import in the designer if the reporting modules adds it to the D scope?

I would think it's possible since there already exists a third-party wrapper module for Apache POI, by Perfect Abstractions: http://blog.perfectabstractions.com/2017/04/05/using-the-pa-office-document-module/