Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I tell an Eclipse plugin where a native library resides for an external plugin?

I have an Eclipse plugin that is a Java wrapper for a C++ library. I'm running on Linux so the wrapper provides a .jar and a .so. I've created a plugin project from this latter existing JAR archive. I have pointed to the .so in the native library location for the jar.

I have another plugin that references this wrapper plugin. I can successfully run a standalone java application from this other plugin that utilizes the wrapper plugin successfully. The class that uses it has to import the java class from the wrapper jar and, before instantiating anything from the wrapper library, I have to call System.loadLibrary. This means I've set the native library location correctly, et cetera.

When I try to do the same kind of operation but within an OSGi context using a product definition, I get a java.lang.UnsatisfiedLinkError. If I edit the run configuration for the product definition to add -Djava.library.path=<full path to the .so>, I am again able to run -- i.e., the library functions properly.

How do I add this path to the plugin configuration? Do I have to create a ClassLoader from my BundleContext inside of my Activator class or is there a plugin configuration way to do this?

I thought I had the right thing by add the path to the .so to the Runtime Classpath in the MANIFEST.MF of my wrapper plugin but that doesn't appear to do it -- I guess it is just for the classpath -- not the library path. Imagine that.

Any ideas?

like image 611
MrMas Avatar asked Dec 26 '22 12:12

MrMas


2 Answers

I do something similar in my project.

In my plugin that depends on native code, I have a folder named os at the root of the plugin, with the following contents:

os
-linux
 -x86
  -<libname>.so
-win32
 -x86
  -<libname>.dll
 -x86_64
  -<libname>.dll

the build.properties specifies (among other things) that the os folder should be packaged as part of the plugin build process:

bin.includes = META-INF/,\
               plugin.xml,\
               lib/,\
               os/,\
               .,\
               schema/

When the product using the plugin runs under one of the platforms for which there is a provided native library, the Java System.loadLibrary("libname") call will resolve the library properly.

This is all being used successfully in my Eclipse 3.6.2 based RCP application. However, I can't find any references that lay out this approach, so I wonder if it's being retired in favor of a more OSGi-friendly approach, using the Bundle-NativeCode directive, which I found several references to:

  • Eclipse Wiki
  • Vogella blog post
  • Blog post
like image 64
sharakan Avatar answered Jan 26 '23 00:01

sharakan


Supposing your library is located file is located at /path/to/your/library/foobar.so

Have you tried this?

cd /path/to/eclipse
export LD_LIBRARY_PATH=/path/to/your/library:$LD_LIBRARY_PATH
./eclipse

The -Djava.library.path property should not include the foobar.so (as per LD_LIBRARY_PATH)

Examples:

-Djava.library.path=/path/to/your/library             #correct
-Djava.library.path=/path/to/your/library/foobar.so   #wrong

export LD_LIBRARY_PATH=/path/to/your/library:$LD_LIBRARY_PATH             #correct
export LD_LIBRARY_PATH=/path/to/your/library/foobar.so:$LD_LIBRARY_PATH   #wrong
like image 33
Luigi R. Viggiano Avatar answered Jan 26 '23 00:01

Luigi R. Viggiano