Ignition 8 - unloading module using dll throws an exception


There are instances when a module uses a custom dll/library loaded using System.loadLibrary(“abcd”) .

The dll must be unloaded when the shutting down/removing a module, or else subsequent loadLibrary() calls won’t work.

A nice hack was posted a while back, it worked fine in Ignition 7: Module using dll - unloading?.

try {
				ClassLoader classLoader = this.getClass().getClassLoader();
				Field field = ClassLoader.class.getDeclaredField("nativeLibraries");
				Vector<Object> libs = (Vector<Object>) field.get(classLoader);
				for (Object o : libs) {
					Method finalize = o.getClass().getDeclaredMethod("finalize", new Class[0]);
					finalize.invoke(o, new Object[0]);
			} catch (Throwable t) {
				lg.tologFatal(true, "Error unloading native resources. " + t.toString());

This hack does not work in Ignition 8, is there an alternative solution?

The line that fails is : Vector libs = (Vector) field.get(classLoader);

And the error is:
java.lang.ClassCastException: class java.util.concurrent.ConcurrentHashMap cannot be cast to class java.util.Vector (java.util.concurrent.ConcurrentHashMap and java.util.Vector are in module java.base of loader ‘bootstrap’)


There doesn’t appear to be a neat hack to workaround this any more.

As of Java 9 native libraries are supposed to get unloaded when the ClassLoader that loaded them gets garbage collected. This means that unless your module has a leak that causes the ClassLoader to hang around, it should eventually get garbage collected and unloaded.

You can test this out by uninstalling your module instead, waiting for a garbage collection event to happen, and then installing it and seeing if you get an error. You can use a tool like VisualVM or JProfiler to trigger a GC or just watch the memory graph in the gateway to see when a GC has happened.