我有两个Eclipse插件:
plugin-1:将.jar中的包提供给其他插件。 (用于C ++库的Java Wrapper)此插件是通过单击File-> New-> Other-> Plug from in Existing JAR Archives创建的。
plugin-2:拥有本机库.so for plugin-1(Bundle-NativeCode
指令在MANIFEST.MF中)并从plugin-1实例化一个类
(我实际上尝试将.so放在plugin-1中,但是我似乎无法加载库,即使插件-1 MANIFEST.MF中的Bundle-NativeCode指令,在包含该插件的插件项目之外。所以,我想我必须将.so与任何使用plugin-1的插件捆绑在一起。)
我正在从plugin-2运行JUnit测试,它从plugin-2实例化MyClass
,然后从插件-1中实例化MyLibraryClass
。 MyClass
成功加载本机库并实例化MyLibraryClass
,而不会在加载本机库或实例化UnsatisfiedLinkError
时抛出MyLibraryClass
或其他异常。在这种情况下我没有运行插件 - 只是JUnit测试。
当我运行plugin-2(使用产品配置)并实例化MyClass
时,本机库加载正常,但在UnsatisifiedLinkError
实例化MyClass
时我得到MyLibraryClass
。在这种情况下,我相信库是根据我使用发布How do I get a list of JNI libraries which are loaded?
注意:我正在使用Eclipse 3.6.1。
这是一个代码示例,展示了我正在尝试做的事情的本质: 包com.mylibrary;
import com.external_library.MyLibraryClass;
public class MyClass {
public static void loadLibrary() {
// Without Bundle-NativeCode in MANIFEST.MF I get
// "java.lang.UnsatisfiedLinkError: no mylibrary_java in java.library.path"
System.loadLibrary("mylibrary_java"); // Loads libmylibrary_java.so.
// Works fine from JUnit Test
// When I run the plugin, I get an UnsatisfiedLinkError:
// "java.lang.UnsatisfiedLinkError:
// com.external_library.MyLibrary_javaJNI.new_MyLibraryClass__SWIG_3()J"
MyLibraryClass instance = new MyLibraryClass();
}
}
答案 0 :(得分:1)
我已经复制了你的设置,我得到了同样的例外。
问题可以通过以下方式解决:
其他一些可能的错误来源: 请注意,对于具有本机绑定的任何类,都不应更改包路径,类名和方法签名。否则JNI将无法找到本机对应物并且您会收到UnsatisfiedLinkError。在您的import指令中,您指定了以下类名com.external_library.MyLibraryClass,但您的错误消息具有不同的类名com.external_library.MyLibrary_javaJNI。检查这些错误来源。
其他一些解释: 与JUnit插件测试相比,JUnit测试不启动OSGi环境。因此,您有一个普通的JUnit测试的普通Java应用程序。如果您的本机lib和您的应用程序包含在同一文件夹(顶层)中,则将在Windows上自动找到本机库。如果在UNIX系统上也是如此,这将解释为什么您的JUnit测试成功。如果它位于不同的文件夹中,则必须为普通Java应用程序指定Java库路径。
MrMas编辑: 通过将.jar文件添加到plugin-2来修改插件-2,使其不依赖于插件-1。
现在您可以使用System.loadLibrary加载库,并使用插件和其他插件中的类。
我选择不修改插件-1,因为它是从现有jar创建的插件,我无法发现如何添加Activator。我选择了将.jar添加到插件-2的路径。有关其他讨论,请参阅Adding jars to a Eclipse PlugIn。
答案 1 :(得分:1)
Bundle-NativeCode
是一个OSGI标记。这意味着只有OSGI类加载器才能使用它。就我而言,我有一个E4-RCP应用程序。一个插件包含Java类。然而,我将本机代码放入一个片段中。
当加载和查找库时,OSGI类加载器有一个片段列表(根据所涉及的结构的命名),并使用类Bundle-NativeCode
检查它们的NativeCodeFinder
。如果遇到麻烦,请尝试在相关功能中添加断点。 getNativePath()
返回OSGIpart读取的条目。