Eclipse RCP/插件问题
我有一个RCP应用程序(简称RCP-APP)。 我创建了一个新插件(称为插件 A),它包装了媒体播放器 api(.jar 文件)和媒体播放器 api 通过 JNA 访问的 C 库 (dll) 文件夹。 然后,我创建了另一个插件(称为插件 B),其中包含依赖于插件 A 的媒体播放器应用程序。
激活插件 B 时,我收到以下错误消息,通知我插件 B 找不到它正在寻找的媒体播放器 .dll:
!ENTRY org.eclipse.jface 4 2 2009-06-22 10:05:22.475 !MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.jface". !STACK 0 java.lang.UnsatisfiedLinkError: Unable to load library 'libvlc': The specified module could not be found. at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:114) at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:157) at com.sun.jna.Library$Handler.(Library.java:123) at com.sun.jna.Native.loadLibrary(Native.java:260) at com.sun.jna.Native.loadLibrary(Native.java:246) at org.videolan.jvlc.internal.LibVlc.(LibVlc.java:41) at org.videolan.jvlc.JVLC.(JVLC.java:45) at com.bah.gs.arts.jekyll.plugins.videolog.VideoLogDisplay.displayStream(VideoLogDisplay.java:32) at com.bah.gs.arts.jekyll.core.extensionpoints.DisplayStreamFactory.getDisplayStreams(DisplayStreamFactory.java:57) at com.bah.gs.arts.jekyll.core.views.medialist.MediaListView$1.doubleClick(MediaListView.java:91) at org.eclipse.jface.viewers.StructuredViewer$1.run(StructuredViewer.java:799) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37) at org.eclipse.core.runtime.Platform.run(Platform.java:880) at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:48) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175) at org.eclipse.jface.viewers.StructuredViewer.fireDoubleClick(StructuredViewer.java:797) at org.eclipse.jface.viewers.AbstractTreeViewer.handleDoubleSelect(AbstractTreeViewer.java:1419) at org.eclipse.jface.viewers.StructuredViewer$4.widgetDefaultSelected(StructuredViewer.java:1173) at org.eclipse.jface.util.OpenStrategy.fireDefaultSelectionEvent(OpenStrategy.java:237) at org.eclipse.jface.util.OpenStrategy.access$0(OpenStrategy.java:234) at org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:295) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3823) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3422) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2384) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2348) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2200) at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:495) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:288) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:490) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at com.bah.gs.arts.jekyll.core.Application.start(Application.java:20) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:193) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:386) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:549) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:504) at org.eclipse.equinox.launcher.Main.run(Main.java:1236) at org.eclipse.equinox.launcher.Main.main(Main.java:1212)
如何通知插件 B(或 RCP-APP)这些 .dll 位于插件 A 的特定文件夹中?
看来 api 希望通过它的环境 PATH 变量找到 .dll。
我如何才能本质上传达“插件 A/文件夹名称”?
感谢你的协助。
I have an RCP application (referred to as RCP-APP). I have created a new plug-in (referred to as plug-in A) that wraps a media player api (.jar file) and a folder of C libraries (dlls) that the media player api accesses via JNA. I then created another plugin (referred to as plug-in B) that contains a media player application that depends on Plug-in A.
When plug-in B is activated I get the following error messages informing me that Plug-in B cannot find the media player .dlls it is looking for:
!ENTRY org.eclipse.jface 4 2 2009-06-22 10:05:22.475 !MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.jface". !STACK 0 java.lang.UnsatisfiedLinkError: Unable to load library 'libvlc': The specified module could not be found. at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:114) at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:157) at com.sun.jna.Library$Handler.(Library.java:123) at com.sun.jna.Native.loadLibrary(Native.java:260) at com.sun.jna.Native.loadLibrary(Native.java:246) at org.videolan.jvlc.internal.LibVlc.(LibVlc.java:41) at org.videolan.jvlc.JVLC.(JVLC.java:45) at com.bah.gs.arts.jekyll.plugins.videolog.VideoLogDisplay.displayStream(VideoLogDisplay.java:32) at com.bah.gs.arts.jekyll.core.extensionpoints.DisplayStreamFactory.getDisplayStreams(DisplayStreamFactory.java:57) at com.bah.gs.arts.jekyll.core.views.medialist.MediaListView$1.doubleClick(MediaListView.java:91) at org.eclipse.jface.viewers.StructuredViewer$1.run(StructuredViewer.java:799) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37) at org.eclipse.core.runtime.Platform.run(Platform.java:880) at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:48) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175) at org.eclipse.jface.viewers.StructuredViewer.fireDoubleClick(StructuredViewer.java:797) at org.eclipse.jface.viewers.AbstractTreeViewer.handleDoubleSelect(AbstractTreeViewer.java:1419) at org.eclipse.jface.viewers.StructuredViewer$4.widgetDefaultSelected(StructuredViewer.java:1173) at org.eclipse.jface.util.OpenStrategy.fireDefaultSelectionEvent(OpenStrategy.java:237) at org.eclipse.jface.util.OpenStrategy.access$0(OpenStrategy.java:234) at org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:295) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3823) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3422) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2384) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2348) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2200) at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:495) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:288) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:490) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at com.bah.gs.arts.jekyll.core.Application.start(Application.java:20) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:193) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:386) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:549) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:504) at org.eclipse.equinox.launcher.Main.run(Main.java:1236) at org.eclipse.equinox.launcher.Main.main(Main.java:1212)
How do I inform Plug-in B (or the RCP-APP) that the .dlls are in a specific folder in Plug-in A?
It appears that the api expects to find the .dlls via it's environment PATH variable.
How can I essentially communicate "plug-in A/Folder-Name"?
Thanks for your assistance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可能想查看插件片段; 这提供了一种机制,使面向公众的 Java API 与(特定于平台的)dll/so 文件分开。
SWT 的打包将是开始研究此类问题的好地方。
You will probably want to look at plugin fragments; this provides a mechanism to keep the public facing Java API apart from the (platform specific) dll/so files.
The packaging of SWT would be a good place to start looking at this sort of problem.
您可以构建一个“二进制文件”插件,将 dll 放入其子文件夹 bin/ 中,然后确保在清单中
* 您添加一个激活器+单例属性。
* 在“构建”、“运行时构建”部分中检查 bin/
在包含二进制插件的功能中,确保选中“安装后解压插件存档”
在二进制插件的激活器中,添加类似的内容这:
我从我的一些代码中复制粘贴,很抱歉它与您的 DLL 示例不完全匹配,我从受限列表中获取可执行路径(请参阅枚举工具)。 最后一步(在文件上设置 +x 标志)对于您的情况可能没有用。 另一方面,您可以免费获得一些异常处理代码和缓存:)并且它经过了相当彻底的测试。
它完成了您想要做的工作,将二进制文件的 url 传递给下游插件。
You could build a "binaries" plugin, put the dll in a subfolder bin/ of it, then make sure in the manifest
* you add an activator + singleton property.
* you check bin/ in the "Build", "Runtime Build" section
In the feature that includes your binaries plug-in, make sure to check "Unpack the plugin archive after installation"
In the activator of your binaries plugin, add something like this :
I copy pasted from some code of mine, so sorry it doesn't perfectly match your DLL example, I was getting executable paths from a restricted list (see enum Tool). The last step (setting the +x flag on the file) is probably useless in your case. On the other hand you get some exception handling code and a cache for free :) And its tested pretty thoroughly.
It does the job you are trying to do, pass the url to the binary to the downstream plugin.
要访问plugin-a/文件夹中的.DLL文件,您需要访问插件A的
Bundle
实例。一种方法是为插件实现一个Activator
-in A 至少扩展Plugin
类(“PluginA
”)。调用
PluginA.getDefault().getBundle().getEntry("folder/some.dll")
将返回 .DLL 文件的 URL。恕我直言,最好将所有直接访问 .DLL 文件的代码放入插件 A 中。这样您就不需要向用户公开插件的内部文件结构。
To get access to the .DLL files in plugin-a/folder you need access to the
Bundle
instance of plug-in A. One way is to implement anActivator
for plug-in A which extends at least the classPlugin
("PluginA
").The call
PluginA.getDefault().getBundle().getEntry("folder/some.dll")
will return an URL to the .DLL file.IMHO it is better to put all code that directly accesses the .DLL files into plug-in A. This way you don't need to expose the internal file structure of your plug-in to its users.