Using libraries in Knime

Hi, I was trying to develop a node that calls some C code with JNI. So, what i did was had the java driver function make a call to this C code, which is stored in a library function (libCode.so). I can get the code to run and work outside of Knime, but when I try to create a node using it, I get the following error when running it:

FATAL KNIME-Worker-0 RapidMind FFT Fatal error
FATAL KNIME-Worker-0 RapidMind FFT org/fft/FastFourierTransformNodeModel.fmain([DI)[D

fmain is the function that is being called in the C code.
I think it's because it's not linked to the library, but I'm not sure. Any ideas? Thanks a lot for your help.

-James

Hi James,

it's most probably a problem with the eclipse class loading mechanism. The log file (which you find in your runtime workspace in the directory .metadata/knime/knime.log) should contain the stack trace of the exception or error that causes the "FATAL" message.

I found a thread (http://dev.eclipse.org/newslists/news.eclipse.platform/msg50598.html) in one of the eclipse newsgroups, which discusses that sort of problems. Maybe that already helps? If you find the solution, please post it here in the forum (and also if it does not work, of course).

Bernd

Thanks a lot for the response, I tried some of the suggestions on that site but nothing really seemed to help. I checked the stack trace, and this was what I got when I got the error:

org.eclipse.swt.SWTError: No more handles (java.lang.UnsatisfiedLinkError: swt-mozilla-gtk-3232 (Not found in java.library.path))
at org.eclipse.swt.SWT.error(SWT.java:3400)
at org.eclipse.swt.SWT.error(SWT.java:3297)
at org.eclipse.swt.browser.Browser.(Browser.java:166)
at org.knime.workbench.helpview.view.HelpView.createPartControl(HelpView.java:91)
at org.eclipse.ui.internal.ViewReference.createPartHelper(ViewReference.java:332)
at org.eclipse.ui.internal.ViewReference.createPart(ViewReference.java:197)
at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:566)
at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:290)
at org.eclipse.ui.internal.ViewPane.setVisible(ViewPane.java:525)
at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:140)
at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:268)
at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:394)
at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1144)
at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:620)
at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:532)
at org.eclipse.ui.internal.PartSashContainer.createControl(PartSashContainer.java:562)
at org.eclipse.ui.internal.PerspectiveHelper.activate(PerspectiveHelper.java:244)
at org.eclipse.ui.internal.Perspective.onActivate(Perspective.java:815)
at org.eclipse.ui.internal.WorkbenchPage.onActivate(WorkbenchPage.java:2429)
at org.eclipse.ui.internal.WorkbenchWindow$6.run(WorkbenchWindow.java:2616)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
at org.eclipse.ui.internal.WorkbenchWindow.setActivePage(WorkbenchWindow.java:2597)
at org.eclipse.ui.internal.WorkbenchWindow.restoreState(WorkbenchWindow.java:1982)
at org.eclipse.ui.internal.Workbench.doRestoreState(Workbench.java:2857)
at org.eclipse.ui.internal.Workbench.access$14(Workbench.java:2805)
at org.eclipse.ui.internal.Workbench$19.run(Workbench.java:1681)
at org.eclipse.ui.internal.Workbench.runStartupWithProgress(Workbench.java:1421)
at org.eclipse.ui.internal.Workbench.restoreState(Workbench.java:1679)
at org.eclipse.ui.internal.Workbench.access$12(Workbench.java:1650)
at org.eclipse.ui.internal.Workbench$17.run(Workbench.java:1529)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
at org.eclipse.ui.internal.Workbench.restoreState(Workbench.java:1473)
at org.eclipse.ui.internal.WorkbenchConfigurer.restoreState(WorkbenchConfigurer.java:183)
at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:702)
at org.eclipse.ui.internal.Workbench.init(Workbench.java:1085)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1847)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:419)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:95)
at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:615)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
at org.eclipse.core.launcher.Main.run(Main.java:977)
at org.eclipse.core.launcher.Main.main(Main.java:952)
Caused by:
java.lang.UnsatisfiedLinkError: swt-mozilla-gtk-3232 (Not found in java.library.path)
at java.lang.ClassLoader.loadLibraryWithPath(ClassLoader.java:957)
at java.lang.ClassLoader.loadLibraryWithClassLoader(ClassLoader.java:926)
at java.lang.System.loadLibrary(System.java:453)
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:123)
at org.eclipse.swt.browser.Browser.(Browser.java:151)
... 50 more

I thought the unsatisfied link error would be with my library file, not a gtk. Any ideas on this one? Thanks again for your help!

-James

Hi James,

the line
org.knime.workbench.helpview.view.HelpView.createPartControl(HelpView.java:91)

leads me to think that the problem (i.e. the stack trace) is totally unrelated to your JNI issue. The class "org.knime.workbench.helpview.view.HelpView" is really only responsible for displaying the node description (this small neat view on the right, which displays information regarding node functionality, in and outport table description etc.). Does the exception also occur if you close the node description window?

(I guess you are using Linux? We are aware that there are some problems with the node description window on Linux but that's something off-topic here.)

Sorry for not being precise on this but I believe the exception that you reported is not related to the JNI problem.

Bernd

Hey, sorry it's taken me a little while to reply, I've been working on this the past few days. The first problem I had was a bad name for the JNI method - I was first compiling my driver, test.java, without the package header and using that test.h file to create the JNI method. However, when there is a package header in the java file, the JNI method changes. For example, my file, test.java, originally had the JNI method Java_test_fmain() with fmain as the function name. With the package header package org.rmfft, the JNI method becomes Java_org_rmfft_test_fmain(). That was the first problem I was having.

Once I got this fixed, I got to the problem I was working on for a while. When I compiled this and tried to run it by typing java test, I got an error saying it couldn't find the class. What I had to do was create two directories, org/rmfft, and place test.java in rmfft and compile it there. Then, i'd have to cd back to the originaly directory (that had org in it) and type java org.rmfft.test. I was then able to run the program through the command line.

Running it in a Knime node was another problem, and I'm still stuck on it. I moved test.java into the package org.rmfft (with the other node files) and I was getting a fatal error having something to do with org.rmfft.test.fmain(). I figured it was because of the above reason, I was putting test.class in the wrong directory, and so it couldn't find the class to run test.fmain(). Oh, and in my NodeModel file, my call to fmain was org.rmfft.test.fmain(). So, I tried putting the test.class file in different directories using the javac -d flag. None of these fixes seemed to help, so I tried deleting test.class in the org.rmfft directory, where it is automatically placed by Knime's compiler. When I ran that, it said that it could not find org.rmfft.test. From this, I'm assuming that Knime finds test.class, but it cannot load fmain for whatever reason, and I'm starting to think it's a problem more with eclipse then with what I'm doing. Any thoughts on this?

-James

Hi James,

I see you made some progress. Java files need to be put into a directory structure that complies with their package definition (typically the first line in the java source code file). If you then execute the class file on the command prompt, you will need to do so from the top most directory (the path is separated by dots). ...but this is one of the details you ignore/forget once you abandon yourself to use eclipse.

I tried to follow your instructions and implemented a C program, which does some heavy calculation on two integers (it adds them up) and returns the result. Following the discussions on the eclipse developer mailing list, I was able to use this code in a KNIME node. I believe the important part is that you put the libCode.so file into the root directory of the plugin. It does work for me (if I use it within KNIME, not only as java application that's started from eclipse!). I was also able to export the plugin and use it in a different knime installation.

I can send you the plugin for your reference, drop me an Email.

Regards,
Bernd