Eclipse RCP / Вопрос о плагине - PullRequest
1 голос
/ 22 июня 2009

У меня есть приложение RCP (называемое RCP-APP). Я создал новый плагин (называемый плагином A), который оборачивает api медиаплеера (файл .jar) и папку библиотек C (dll), к которой api медиаплеера обращается через JNA. Затем я создал другой плагин (называемый плагином 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 ожидает найти DLL-файлы через переменную окружения PATH.

Как я могу по существу сообщить "плагин A / имя папки" ?

Спасибо за вашу помощь.

Ответы [ 3 ]

1 голос
/ 27 июня 2009

Возможно, вы захотите посмотреть на фрагменты плагина; это обеспечивает механизм, позволяющий отделить общедоступный интерфейс Java API от файлов dll / so (для конкретной платформы).

Упаковка SWT была бы хорошим местом, чтобы начать смотреть на такого рода проблему.

1 голос
/ 22 июня 2009

Чтобы получить доступ к файлам .DLL в папке plugin-a /, вам нужен доступ к экземпляру Bundle плагина A. Один из способов - реализовать Activator для плагина A, который расширяет как минимум класс Plugin ("PluginA").

Вызов PluginA.getDefault().getBundle().getEntry("folder/some.dll") вернет URL-адрес файла .DLL.

ИМХО, лучше поместить весь код, который непосредственно обращается к файлам .DLL, в плагин A. Таким образом, вам не нужно показывать внутреннюю файловую структуру вашего плагина его пользователям.

0 голосов
/ 03 июля 2015

Вы можете создать плагин "binaries", поместить dll в подпапку bin / of этого, а затем убедиться в манифесте. * Вы добавляете свойство активатор + синглтон. * Вы проверяете bin / в разделе «Build», «Runtime Build»

В функции, включающей плагин для двоичных файлов, обязательно установите флажок «Распаковать архив плагина после установки»

В активаторе вашего бинарного плагина добавьте что-то вроде этого:

public enum Tool {reach, ctl, ltl};
private static URI toolUri [] = new URI [3];

public static URI getProgramURI(Tool tool) throws IOException {
    if (toolUri[tool.ordinal()] == null) {
        String relativePath = "bin/its-"+ tool.toString() ;
        URL toolff = getDefault().getBundle().getResource(relativePath);
        if (toolff == null) {
            log.severe("unable to find an executable [" + tool + "] in path " + relativePath);
            Enumeration<URL> e = getDefault().getBundle().findEntries("bin/", "*", true);
            log.fine("Lising URL available in bin/");
            while (e.hasMoreElements()) {
                log.finer(e.nextElement().toString());
            }
            throw new IOException("unable to find the tool binary");
        }
        URL tmpURL = FileLocator.toFileURL(toolff);

        // use of the multi-argument constructor for URI in order to escape appropriately illegal characters
        URI uri;
        try {
            uri = new URI(tmpURL.getProtocol(), tmpURL.getPath(), null);
        } catch (URISyntaxException e) {
            throw new IOException("Could not create a URI to access the binary tool :", e);
        }
        toolUri[tool.ordinal()] = uri;
        log.fine("Location of the binary : " + toolUri);

        File crocExec = new File(uri);
        if (!crocExec.setExecutable(true)) {
            log.severe("unable to make the command-line tool executable [" + toolUri + "]");
            throw new IOException("unable to make the command-line tool executable");
        }       

    }
    return toolUri[tool.ordinal()];
}

Я скопировал вставленный из некоторого моего кода, так что извините, он не совсем соответствует вашему примеру с DLL, я получал пути к исполняемым файлам из ограниченного списка (см. Enum Tool). Последний шаг (установка флага + x в файле), вероятно, бесполезен в вашем случае. С другой стороны, вы получаете некоторый код обработки исключений и кеш бесплатно :) И он довольно тщательно протестирован.

Он выполняет ту работу, которую вы пытаетесь выполнить, передавая URL-адрес двоичного файла последующему плагину.

...