JXBrowser在OSGi应用程序中有多个StartIPCTasks。如何正确重新初始化浏览器?

时间:2017-08-31 00:20:14

标签: osgi osgi-bundle jxbrowser

我正在OSGi应用程序中使用JXBrowser插件进行工作,但是当我更新插件时出现此错误:

JXBrowser multiple instance error

我无法在StartIPCTask上找到任何信息,但我知道它是在实例化浏览器时运行的。我试图始终使用相同的路径指定BrowserContext,但我得到相同的错误。我还尝试在更新应用程序时处理浏览器对象(以及可选地运行BrowserCore.shutdown()),但是我收到相同的错误或者全部崩溃。

是否有一些特殊的方法来垃圾收集浏览器并确保StartIPCTask只实现一次?我可以通过编程方式指定哪一个未定义?谢谢!

修改 不幸的是,我无法发布我的所有代码,但项目的要点是将JXBrowser封装在应用程序中。因此,当创建应用程序时,它会调用start函数,其中包含:

try {
    browser = new Browser();
    browserView = new BrowserView(browser);
    browser.addScriptContextListener(new ScriptContextAdapter() {
        @Override
        public void onScriptContextCreated(ScriptContextEvent event) {
            Browser browser = event.getBrowser();
            JSValue window = browser.executeJavaScriptAndReturnValue("window");
            window.asObject().setProperty("browser", browser);
        }
    });
} catch (IPCException exception) {
    System.out.println("Must restart to use browser");
    // This executes after a 1 minute delay (shown below)
}

在重新安装应用以进行更新之前,会调用shutdown()方法,现在只是:

if (browser != null)
    browser.dispose();

根据文档,由于我使用的是Mac OSX,因此必须手动处理浏览器和BrowserContexts。但添加任一功能都没有效果。

当重新加载应用程序时,再次运行start方法并且browser声明行失败,并显示以下错误:

objc[71371]: Class StartIPCTask is implemented in both 
/path/to/karaf_data/tmp/jxbrowser-chromium-55.0.2883.87.6.14.2/data/Temp/libjxbrowser-common64-fb50af13-9fbf-4fe0-a9cf-0a1f9d1201a7.dylib (0x144e95610) 
and /path/to/karaf_data/tmp/jxbrowser-chromium-55.0.2883.87.6.14.2/data/Temp/libjxbrowser-common64-29e240a5-75e5-4ece-9fe7-33dd8b3245cb.dylib (0x180db9610).
One of the two will be used. Which one is undefined.

但是没有选项可以指定哪个是未定义的。相反,它会保持冻结约1分钟,然后代码继续browser为空。

我应该指定BrowserContext.defaultContext()以外的BrowserContext吗?如何在不退出父应用程序的情况下通知BrowserCore退出,然后我可以创建一个新的浏览器吗?

1 个答案:

答案 0 :(得分:0)

您会看到此错误,因为您的OSGI应用程序使用不同的ClassLoader来加载JNI库,这是JxBrowser的一部分。 libjxbrowser-common64 ... dylib是一个单独的JNI库。如果您尝试使用不同的ClassLoader加载它,则会发生上述错误。这是基于JNI-OSGI部分不兼容性的众所周知的限制。 同样在MacOSX中,Chromium进程作为Java进程的一部分运行,并且在多个JxBrowser实例配置中,Chromium可能具有意外行为。 要解决此问题,我建议您将Chromium作为外部进程运行,例如使用-Djxbrowser.ipc.external = true VM参数,找到使用不同ClassLoader为JxBrowser库禁止OSGI环境的方法。