1

我有两个 Eclipse 插件:

  • plugin-1:为其他插件提供 .jar 包。(用于 C++ 库的 Java 包装器)此插件是通过单击现有 JAR 档案中的文件->新建->其他->插件创建的。

  • plugin-2:拥有plugin-1的本地库.so(Bundle-NativeCode指令在MANIFEST.MF中)并从plugin-1实例化一个类

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

我正在从插件 2 运行 JUnit 测试,它从插件 2 实例化,而插件 2又从插件 1MyClass实例化。成功加载本机库并实例化,而不会从本机库的加载或从实例化中引发其他异常。在这种情况下,我没有运行插件——只是 JUnit 测试。MyLibraryClassMyClassMyLibraryClassUnsatisfiedLinkErrorMyLibraryClass

当我运行 plugin-2 (使用产品配置)并实例化MyClass时,本机库加载正常,但我得到一个UnsatisifiedLinkErrorwhen MyClassinstantiates MyLibraryClass在这种情况下,我相信该库是根据我使用发布如何获取已加载的 JNI 库列表中描述的类获得的输出加载的?

注意:我使用的是 Eclipse 3.6.1。

这是一个代码示例,它显示了我正在尝试做的事情的本质: package 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(); 

    }
}
4

2 回答 2

1

我已经复制了你的设置,我得到了同样的例外。

该问题可以通过以下方式解决:

  • 将本机库添加到 plugin-1
  • 将 Bundle-NativeCode 指令添加到插件 1 的清单中
  • 在 plugins-1 的 Activator 的静态构造函数中加载库(可以自己写一个添加到插件中)

其他一些可能的错误来源: 请注意,对于任何具有本机绑定的类,永远不要更改包路径、类名和方法签名。否则 JNI 将无法找到本地对应项,并且您会收到 UnsatisfiedLinkError。在您的导入指令中,您指定了以下类名 com.external_library.MyLibraryClass,但您的错误消息具有不同的类名 com.external_library.MyLibrary_javaJNI。检查这些错误来源。

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

由 MrMas 编辑:通过将 .jar 文件添加到 plugin-2 来修改 plugin-2,使其不依赖于 plugin-1。

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

现在您可以使用 System.loadLibrary 加载库,并使用插件内部和另一个插件中的类。

我选择不修改 plugin-1,因为它是从现有 jar 中创建的插件,我无法发现如何添加 Activator。相反,我选择了将 .jar 添加到 plugin-2 的路径。有关其他讨论,请参阅将 jars 添加到 Eclipse 插件。

于 2013-04-05T17:10:33.380 回答
1

Bundle-NativeCode是一个 OSGI 标记。这意味着只有 OSGI 类加载器在使用它。就我而言,我有一个 E4-RCP 应用程序。一个插件包含 Java 类。但是,我将本机代码放入一个片段中。

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

于 2016-05-27T10:24:48.307 回答