JXBrowser multiple StartIPCTasks in OSGi application. How to reinitialize Browser properly?

232 views Asked by At

I'm working on a JXBrowser plugin in an OSGi application for work, but when I update the plugin I get this error:

JXBrowser multiple instance error

I can't find any information on the StartIPCTask, but I know it is run when a Browser is instantiated. I tried to specify BrowserContext with the same path always, but I get the same error. I also tried disposing of the browser object (and optionally running BrowserCore.shutdown()) when the app is updated but I get the same error or it all crashes.

Is there some special way to garbage collect browsers and ensure that the StartIPCTask is only implemented once? Can I specify which one is undefined programmatically? Thanks!

EDIT: Unfortunately I can't post all my code but the gist of the project is encapsulating JXBrowser in an app. So when the app is created it calls a start function, which contains:

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)
}

Before the app is reinstalled for an update, the shutdown() method is called, which right now is just:

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

According to the documentation, since I am on Mac OSX, Browsers and BrowserContexts must be manually disposed. But adding either function has no effect.

When the app is then reloaded, the start method is run again and the browser declaration line fails with the following error:

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.

But there is no option to specify which is undefined. So instead, it remains frozen for ~1 minute, then the code continues with browser as null.

Should I be specifying a BrowserContext other than the BrowserContext.defaultContext()? How do I inform the BrowserCore to exit without exiting the parent application, and can I then create a new Browser?

1

There are 1 answers

0
Nikita Shvinagir On BEST ANSWER

You see this error because your OSGI application uses different ClassLoaders to load JNI library which is a part of JxBrowser. The libjxbrowser-common64...dylib is a singleton JNI library. If you try loading it with different ClassLoaders, the error mentioned above happens. This is a well known limitation based on JNI-OSGI partial incompatibility. Also in MacOSX the Chromium process is run as a part of Java process and in the multiple JxBrowser instances configuration Chromium might have an unexpected behavior. To resolve this issue I suggest that you run Chromium as an external process, e.g. using the -Djxbrowser.ipc.external=true VM parameter, and find the way to forbid OSGI environment using different ClassLoaders for JxBrowser library.