首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UnsatisfiedLinkError:库加载,但我仍然得到一个链接错误

UnsatisfiedLinkError:库加载,但我仍然得到一个链接错误
EN

Stack Overflow用户
提问于 2013-04-04 22:13:51
回答 2查看 3.1K关注 0票数 1

我有两个Eclipse插件:

  • plugin-1:在.jar中为其他插件提供一个包。( C++库的Java包装器)这个插件是通过单击现有JAR档案中的File->New->Other->插件创建的。
  • plugin-2:具有插件-1的本机库.so (Bundle-NativeCode指令在MANIFEST.MF中),并从plugin-1实例化一个类。

(实际上,我尝试将.so放在plugin-1中,但我似乎无法加载库,即使在包含.so的插件项目之外的插件-1 MANIFEST.MF中使用Bundle-NativeCode指令,所以我想我必须将.so与任何使用插件-1的插件捆绑在一起。)

我正在从plugin-2运行一个JUnit测试,它从plugin-2实例化MyClass,然后从plugin-1实例化MyLibraryClassMyClass成功地加载了本机库并实例化了MyLibraryClass,而没有从加载本机库或实例化MyLibraryClass引发UnsatisfiedLinkError或其他异常。在这种情况下,我不运行插件--只运行JUnit测试。

当我运行插件-2(使用产品配置)并实例化MyClass时,本机库加载得很好,但是当MyClass实例化MyLibraryClass时,我得到了一个MyLibraryClass。在这种情况下,我相信库是基于我从使用posting How do I get a list of JNI libraries which are loaded?中描述的类获得的输出来加载的。

注意:我正在使用Eclipse3.6.1。

下面是一个代码示例,它展示了我要做的事情的本质: package com.mylibrary;

代码语言:javascript
复制
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(); 

    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-05 17:10:33

我复制了您的设置,并得到了相同的例外。

问题可以通过:来解决

  • 将本机库添加到plugin-1。
  • 将Bundle-NativeCode指令添加到plugin-1的说明中。
  • 在plugins-1的Activator的静态构造函数中加载库(您可以编写一个并将其添加到插件中)

其他一些可能的错误来源:要知道,对于任何具有本机绑定的类,都不应该更改包路径、类名和方法签名。否则,JNI将无法找到本机对应方,您将得到一个UnsatisfiedLinkError。在导入指令中,您指定了以下类名com.external_library.MyLibraryClass,但是您的错误消息有不同的类名com.external_library.MyLibrary_javaJNI。检查这些错误的来源。

的一些附加解释:A JUnit测试与JUnit插件测试不同,它不启动OSGi环境。因此,您有一个普通的JUnit测试的普通Java应用程序。如果本机库和应用程序包含在同一个文件夹(顶级)中,则本机库将自动在windows上找到。如果在UNIX系统上也是如此,这将解释为什么您的JUnit测试是成功的。如果它位于另一个文件夹中,则必须为普通Java应用程序指定Java路径。

编辑由MrMas:修改插件-2,所以它不依赖于插件-1添加.jar文件到插件-2。

  1. 将.jar文件复制到插件-2中。我将它放在与.so相同的目录中。
  2. 通过以下方式将jar添加到项目中: project ->Properties->Libraries> Add
  3. 通过plugin.xml->Runtime->ClassPath部分-> Add将jar添加到类路径
  4. 从Jar导出包(如果下游插件需要的话)
  5. 从plugin.xml->依赖项中删除plugin-1的依赖项

现在,您可以使用System.loadLibrary加载库,并从插件和其他插件中使用这些类。

我选择不修改plugin-1,因为它是作为现有jar中的插件创建的,而我无法了解如何向其中添加Activator。相反,我选择了将.jar添加到插件-2的路径。有关更多讨论,请参见Adding jars to a Eclipse PlugIn

票数 1
EN

Stack Overflow用户

发布于 2016-05-27 10:24:48

Bundle-NativeCode是OSGI标签.这意味着只有OSGI类加载器使用它。就我而言,我有一份E4-RCP申请。一个插件包含Java类。然而,我将本机代码放入一个片段中。

在加载和查找库时,OSGI类加载器有一个片段列表(根据所涉及的结构的命名),并使用类Bundle-NativeCode检查它们的NativeCodeFinder。如果有问题,请尝试在相关函数中添加断点。getNativePath()返回由OSGIpart读取的条目。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15822694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档