【问题标题】:How do I tell an Eclipse plugin where a native library resides for an external plugin?如何告诉 Eclipse 插件本地库驻留在外部插件的位置?
【发布时间】:2013-01-04 01:20:38
【问题描述】:

我有一个 Eclipse 插件,它是 C++ 库的 Java 包装器。我在 Linux 上运行,因此包装器提供了一个 .jar 和一个 .so。我从后一个现有的 JAR 存档创建了一个插件项目。我已经在 jar 的本机库位置中指向了 .so。

我有另一个插件引用了这个包装插件。我可以从这个其他插件成功地运行一个独立的 java 应用程序,该插件成功地利用了包装器插件。使用它的类必须从包装器 jar 中导入 java 类,并且在从包装器库中实例化任何内容之前,我必须调用 System.loadLibrary。这意味着我已经正确设置了本机库位置,等等。

当我尝试使用产品定义在 OSGi 上下文中执行相同类型的操作时,我收到 java.lang.UnsatisfiedLinkError。如果我编辑产品定义的运行配置以添加-Djava.library.path=<full path to the .so>,我就可以再次运行——即库正常运行。

如何将此路径添加到插件配置中?我是否必须从我的 Activator 类中的 BundleContext 创建一个 ClassLoader,或者是否有插件配置方法可以做到这一点?

我认为通过将 .so 的路径添加到我的包装器插件的 MANIFEST.MF 中的运行时类路径中,我做对了,但这似乎并没有这样做——我想这只是为了类路径-- 不是库路径。想象一下。

有什么想法吗?

【问题讨论】:

  • 不清楚您是否使用 OSGi 规范中的 Bundle-NativeCode 标头?这不应该要求您设置任何环境。路径。

标签: java eclipse eclipse-plugin osgi


【解决方案1】:

我在我的项目中做了类似的事情。

在我的依赖本机代码的插件中,我在插件的根目录下有一个名为 os 的文件夹,内容如下:

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

build.properties 指定(除其他外)应将 os 文件夹打包为插件构建过程的一部分:

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

当使用插件的产品在提供本机库的平台之一下运行时,Java System.loadLibrary("libname") 调用将正确解析库。

这一切都在我基于 Eclipse 3.6.2 的 RCP 应用程序中成功使用。但是,我找不到任何介绍这种方法的参考资料,所以我想知道它是否会被淘汰,转而使用 Bundle-NativeCode 指令来支持更适合 OSGi 的方法,我找到了几个参考资料:

【讨论】:

  • bin.includes 已按照您的建议设置。我还尝试将 Bundle-NativeCode 指令添加到我的包装插件 MANIFEST.MF。这些都不起作用。什么起作用(这令人困惑)是将(没有 Bundle 指令) -Djava.library.path=lib/ 添加到使用包装器的插件中!为什么?我的插件中没有 lib/ 目录,但在 wrapper 插件中有。为什么在使用包装器的插件中设置库路径以及包装器的相对路径?然而,该解决方案满足了便携性需求。然而,一个解释会很好。
  • 是文件夹结构中的本机库,但与我的布局相匹配?操作系统和架构标签必须匹配。
  • 我的理解是 RCP 有效地将 -Djava.library.path 指令添加到 /os// 目录,适用于产品运行的任何操作系统和 ARCH . bin.includes 指令只是确保 os 目录被包含在编译的插件中,它本身并不告诉 RCP/OSGi 任何关于它的内容。
  • 关于我如何使用它,我有一个包含本机代码和一些 Java 代码的插件 A。插件 A 中的 Java 代码是访问该本地库的唯一 Java 代码。
  • 我最初并不知道我需要根据您概述的结构设置我的目录,只是带有 .so 的目录在 build.includes 中。在我看来,除了您已经布置的内容之外,您还必须添加 Bundle-NativeCode 才能使其正常工作。我在没有这个指令和这个指令的情况下尝试了你的建议,但仍然没有运气。您是否使用一个插件使用包含本机库的不同插件的类来执行此操作?
【解决方案2】:

假设你的库位于文件位于 /path/to/your/library/foobar.so

你试过吗?

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

-Djava.library.path 属性不应包含 foobar.so(根据 LD_LIBRARY_PATH)

例子:

-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

【讨论】:

  • 感谢您的回复。我已经走上了这条路。它可以工作,但不允许我设置插件以便它可以开箱即用。
猜你喜欢
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 2021-06-10
  • 1970-01-01
  • 2012-01-13
  • 2011-03-06
相关资源
最近更新 更多