Java Snippet - having two Java Snippets using a JNI library causes UnsatisfiedLinkError.

I have a native library, Proteax Desktop, that can be used from Java via JNI. I can successfully use it from a Java snippet like this


<Global vars>
com.biochemfusion.proteax.ProteaxDesktop proteax = new com.biochemfusion.proteax.ProteaxDesktop();

<Method Body>
try {
  return proteax.mw_avg($Col0$);
} catch (Exception e) {
  return -1.0;
}

and this will calculate the average molecular weight of protein sequences in the first column. OK. <Yes, the error handling above is rather terrible - but I am not yet familiar with how to properly pass errors around in KNIME>


However, if I add a second Java Snippet that has the same code to the workflow, I get a


  ERROR     Java Snippet     Configure failed (UnsatisfiedLinkError): Native Library C:\Apps\knime_2.3.1\proteax_desktop_intf.dll already loaded in another classloader

as soon as the node is configured.

The ProteaxDesktop class does a "System.loadLibrary("proteax_desktop_intf");" as the first thing in its constructor. This doesn't pose any problems when used in a normal Java application, so I can run this code without problems:

        ProteaxDesktop proteax = new ProteaxDesktop();
        ProteaxDesktop proteax2 = new ProteaxDesktop();        

But it seems to be a problem when ProteaxDesktop is loaded via classloaders in KNIME ?
What's the recommended way to resolve this issue ? I assume that when I develop KNIME nodes these will be loaded only once as components and then the issue is gone (?). But it will still be confusing if the library cannot be used from a Java Snippet.

As a test, I tried ignoring the UnsatisfiedLinkError with this construct in the ProteaxDesktop constructor

try { System.loadLibrary("proteax_desktop_intf"); }
catch (UnsatisfiedLinkError e) { /* OK, expected. */ }
 

but that caused subsequent native calls to fail in the second node (first node still worked fine).


Cheers
-- Jan Holst Jensen, Biochemfusion

If native libraries are involved, the best way is to put them in a separate plugin. The library can then be loaded once when KNIME starts up. This eliminates the errors you get. As a nice side-effect you do not need to specify any paths for the native libraries or put them in some special places. You may have a look at the RDKit nodes from the community contributions. It contains native libraries for five different operating systems.

OK, thanks. I'll have a look at the examples.

Cheers // -- Jan