Issues with Module Including JNI

Hi Everyone,

I’m trying to build a module using a local .jar file which includes a JNI for Windows (.dll). I can successfully build the module however I’m getting the error below when the module starts up. This error seems to indicate that there is an issue loading the dll. Are there any restrictions on loading .dll’s into a module?

Something which might be related - in order to get a stand-alone java project to use the classes in the .jar the VM requires following option: –add-opens java.base/java.lang=ALL-UNNAMED

This is due to the .jar using illegal reflective access. Are there any restrictions on the Ignition platform in regards to this?

Note:

  • I’ve also included the .dll as an artifact in the project structure within IntelliJ.
  • The .jar was compiled using Java 8 and I don’t have access to the source code except through the FernFlower decompiler.
java.lang.ExceptionInInitializerError: null
at com.inductiveautomation.ignition.examples.tagdriver.configuration.ValueSimulator.(ValueSimulator.java:31)
at com.inductiveautomation.ignition.examples.tagdriver.ExampleDevice.(ExampleDevice.java:35)
at com.inductiveautomation.ignition.examples.tagdriver.configuration.ExampleDeviceType.createDevice(ExampleDeviceType.java:50)
at com.inductiveautomation.ignition.gateway.opcua.server.DeviceManager.createDevice(DeviceManager.kt:184)
at com.inductiveautomation.ignition.gateway.opcua.server.DeviceManager.createAndStartupDevice(DeviceManager.kt:203)
at com.inductiveautomation.ignition.gateway.opcua.server.DeviceManager.registerDeviceType(DeviceManager.kt:157)
at com.inductiveautomation.ignition.gateway.opcua.OpcUaExtensionManager.registerDeviceType(OpcUaExtensionManager.kt:35)
at com.inductiveautomation.ignition.gateway.opcua.server.api.AbstractDeviceModuleHook.serviceReady(AbstractDeviceModuleHook.kt:50)
at com.inductiveautomation.ignition.gateway.services.ModuleServicesManagerImpl.subscribe(ModuleServicesManagerImpl.java:96)
at com.inductiveautomation.ignition.gateway.opcua.server.api.AbstractDeviceModuleHook.startup(AbstractDeviceModuleHook.kt:37)
at com.inductiveautomation.ignition.examples.tagdriver.ModuleHook.startup(ModuleHook.java:27)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl$LoadedModule.startup(ModuleManagerImpl.java:2433)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.startupModule(ModuleManagerImpl.java:1226)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl$4.call(ModuleManagerImpl.java:881)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.executeModuleOperation(ModuleManagerImpl.java:947)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.restartModuleInternal(ModuleManagerImpl.java:861)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.restartModule(ModuleManagerImpl.java:853)
at com.inductiveautomation.ignition.gateway.web.pages.config.ModulePage$RestartAction.execute(ModulePage.java:575)
at com.inductiveautomation.ignition.gateway.web.components.ConfirmationPanel$1.onClick(ConfirmationPanel.java:50)
at org.apache.wicket.markup.html.link.Link.onLinkClicked(Link.java:190)
at jdk.internal.reflect.GeneratedMethodAccessor50.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.apache.wicket.RequestListenerInterface.internalInvoke(RequestListenerInterface.java:258)
at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:216)
at org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.invokeListener(ListenerInterfaceRequestHandler.java:243)
at org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.respond(ListenerInterfaceRequestHandler.java:236)
at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:890)
at org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:64)
at org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:261)
at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:218)
at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:289)
at org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(WicketFilter.java:259)
at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:201)
at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:282)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1596)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:545)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:590)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1607)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1297)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:485)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1577)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1212)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:322)
at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:59)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:500)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:547)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:270)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:388)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException: null
at java.base/java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.base/java.lang.Runtime.loadLibrary0(Unknown Source)
at java.base/java.lang.System.loadLibrary(Unknown Source)

You may have to manually put the DLL file on one of the paths in whatever java.library.path is on your system. You can print it out when your module starts up to see.

1 Like