Javascript-Java-Bridge иногда не работает (JxBrowser 6.3)

У меня возникли проблемы с последней версией jxBrowser.
Я добавил javascript-java-bridge с onScriptContextCreated:

        mainBrowser.addScriptContextListener(new ScriptContextAdapter()
    {
        @Override
        public void onScriptContextCreated(ScriptContextEvent event)
        {
            Browser browser = event.getBrowser();
            JSValue jsValue = browser.executeJavaScriptAndReturnValue("window");
            jsValue.asObject().setProperty("app", new JavascriptBridge());
            logger.info("Set app context in JS");

        }
    });

В JS у меня есть функция gwtAdapter, в которой вызываются две Java-функции:

function gwtAdapter(name, params, callback)
{

try
{
    if (name == "saveSelectedLoginData")
    {
        app.sendMessageNew(name, params, callback);

        console.log("DURCH DURCH DURCH");
    }
    else
    {
        console.log("Call sendMessage: \n\tName:" + name + "\n\tParams: " + params);

        app.sendMessage(name, [params]);

        console.log("Call sendMessage: \n\tName:" + name + "\n\tCallback: " + callback);
        app.setMessageCallback(name, callback);
    }

}
catch(err)
{
    console.log("Error in gwtAdapter: " + err.message);
}
}

Пожалуйста, не обсуждайте разумность этих функций ;) У них есть причина.
В некоторых случаях браузер зависает, когда он достигает app.sendMessage, и тогда я не получаю ни логов, ни сообщения об ошибке. Тогда я больше не могу взаимодействовать с консолью DevTools.

Я не знаю, какую информацию мне следует добавить, потому что я не могу найти что-то полезное, что можно было бы добавить.
LogLevel уже находится на уровне Level.ALL.

Если у вас есть вопросы, пожалуйста, не стесняйтесь спрашивать, чтобы я мог что-то добавить.

Редактировать_1:

jxbrowser-browser.log:

Mai 10, 2016 11:51:04 AM com.teamdev.jxbrowser.chromium.BrowserType getDefault
INFORMATION: JxBrowser type: HEAVYWEIGHT

jxbrowser-chromium.log: пусто

jxbrowser-ipc.log: ничего полезного для этой ошибки не регистрируется.

Редактировать_2:

Странно... После зависания прошло около 8 минут, чтобы пройти функцию, но после этого javascript-java-мост сломался.

Вот некоторые логи:

Mai 10, 2016 2:52:55 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  OnConsoleMessage{type=OnConsoleMessage, uid=907, level=0, message='Save LoginData now!', lineNumber=568, sourceId='file:///workspace/xxxxxxx/processes/Contents/Login/js/functions.js'}, SocketInfo{cid=0, bid=0, channelType=Browser}
Mai 10, 2016 2:52:55 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  OnInvokeJSJavaMessage{type=OnInvokeJSJavaEvent, uid=13, javaObjectId=0, contextPtr=140448130669824, methodName='sendMessageNew', parameters='s21:saveSelectedLoginData:s158:{"saveLoginData": {"selectedUser": "testuser", "selectedPassword": "testuser", "selectedSystem": "xxxxxx", "selectedLanguage": "de"}}:of140448149924128:', returnValue='', errorMessage=''}, SocketInfo{cid=0, bid=0, channelType=Render}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelWriter run
INFORMATION: WRITE: OnInvokeJSJavaMessage{type=OnInvokeJSJavaEvent, uid=12, javaObjectId=0, contextPtr=140448130669824, methodName='setMessageCallback', parameters='s6:getUrl:of140448129618576:', returnValue='', errorMessage='Failed to send message.'}, SocketInfo{cid=0, bid=0, channelType=Render}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelWriter run
INFORMATION: WRITE: ExecuteJavaScriptMessage{type=ExecuteJavaScript, uid = 40, frameId=-1, javaScript='window', hasReturnValue=true, returnValue='null'}, SocketInfo{cid=0, bid=0, channelType=Render}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  ExecuteJavaScriptMessage{type=ExecuteJavaScript, uid = 40, frameId=-1, javaScript='window', hasReturnValue=true, returnValue='oo140448128891328:'}, SocketInfo{cid=0, bid=0, channelType=Render}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelWriter run
INFORMATION: WRITE: JSInvokeFunctionMessage{type=JSInvokeFunction, uid=41, objectPtr=140448128891328, functionPtr=140448149924128, contextPtr=140448130669824, frameId=-1, args='on:', result='null', error='null'}, SocketInfo{cid=0, bid=0, channelType=Render}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  JSInvokeFunctionMessage{type=JSInvokeFunction, uid=41, objectPtr=140448128891328, functionPtr=140448149924128, contextPtr=140448130669824, frameId=-1, args='on:', result='ou:', error=''}, SocketInfo{cid=0, bid=0, channelType=Render}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelWriter run
INFORMATION: WRITE: OnInvokeJSJavaMessage{type=OnInvokeJSJavaEvent, uid=13, javaObjectId=0, contextPtr=140448130669824, methodName='sendMessageNew', parameters='s21:saveSelectedLoginData:s158:{"saveLoginData": {"selectedUser": "testuser", "selectedPassword": "testuser", "selectedSystem": "xxxxxxx", "selectedLanguage": "de"}}:of140448149924128:', returnValue='', errorMessage=''}, SocketInfo{cid=0, bid=0, channelType=Render}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  OnConsoleMessage{type=OnConsoleMessage, uid=1119, level=0, message='voidFunction called', lineNumber=1153, sourceId='file:///workspace/xxxxxxxxx/processes/Contents/Login/js/functions.js'}, SocketInfo{cid=0, bid=0, channelType=Browser}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  OnConsoleMessage{type=OnConsoleMessage, uid=1120, level=0, message='voidFunction-response: null', lineNumber=1156, sourceId='file:///workspace/xxxxxx/processes/Contents/Login/js/functions.js'}, SocketInfo{cid=0, bid=0, channelType=Browser}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  OnConsoleMessage{type=OnConsoleMessage, uid=1121, level=0, message='DURCH DURCH DURCH', lineNumber=95, sourceId='file:///workspace/xxxxxx/processes/Contents/Login/js/functions.js'}, SocketInfo{cid=0, bid=0, channelType=Browser}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  JSInvokeFunctionMessage{type=JSInvokeFunction, uid=39, objectPtr=140448151648656, functionPtr=140448129618576, contextPtr=140448130669824, frameId=-1, args='s234:{"response":{"url":"xxxxxxxxx"},"exceptions":{},"success":true}:', result='xxxxxxxx', error=''}, SocketInfo{cid=0, bid=0, channelType=Render}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  OnConsoleMessage{type=OnConsoleMessage, uid=1122, level=0, message='Login now!', lineNumber=570, sourceId='file:///workspace/xxxxx/processes/Contents/Login/js/functions.js'}, SocketInfo{cid=0, bid=0, channelType=Browser}
Mai 10, 2016 3:01:15 PM com.teamdev.jxbrowser.chromium.internal.ipc.MemoryChannelReader a
INFORMATION: READ:  OnConsoleMessage{type=OnConsoleMessage, uid=1123, level=0, message='Error in gwtAdapter: undefined', lineNumber=110, sourceId='file:///workspace/xxxxxx/processes/Contents/Login/js/functions.js'}, SocketInfo{cid=0, bid=0, channelType=Browser}

Я заменил некоторые детали на xxxxxx

Редактировать_3:

Думаю, я понял. Может быть, это ошибка?

Сначала какой-то код:

function testFunction()
{
    gwtAdapter("testFunction", '{"gwtIndexGuiReady":true, "xxxxx":1000, "isNewItem":true}', testFunc2);
}

function testFunc2()
{
    gwtAdapter("testFunc2", '{"gwtIndexGuiReady":true, "xxxxx":1000, "isNewItem":true}', voidFunction);
}

function voidFunction(response)
{
    console.log("voidFunction called");
    if(typeof response !== 'undefined')
    {
        console.log("voidFunction-response: " + response);
    }
}

Действия по воспроизведению ошибки:

  1. Запустить JxBrowser
  2. Открыть инструменты разработчика
  3. Установите точку останова на app.sendMessage в gwtAdapter
  4. Вызовите testFunction();
  5. Посмотрите, как мост работает неправильно при втором вызове gwtAdapter.

Первый вызов функции (sendMessage из testFunction) работает нормально, но второй вызов функции (sendMessage из testFunc2) не будет работать.

Небольшое объяснение:

последний параметр из gwtAdapter — это обратный вызов, который будет выполняться из Java (где функция — это обратный вызов в виде JSFunction):

    JSValue jsValue = mainBrowser.executeJavaScriptAndReturnValue("window");

    logger.info("Call callback for: " + name);

    function.invoke(jsValue.asObject(), messageMap.get(name));

в этом обратном вызове есть еще один вызов gwtAdapter, и sendMessage прервется там, или, другими словами, он зависнет в sendMessage примерно на 8:30 минут, а затем передаст эту функцию.

Редактировать_4:

Может быть, это проблема с потоками? Я думаю, что он выполняет обратный вызов javascript, и в этом обратном вызове он пытается выполнить функцию в Java (sendMessage). Я думаю, что он не может выполнять javascript и принимать вызовы параллельно.


person dominic.e    schedule 10.05.2016    source источник
comment
Сообщения журнала очень важны в этом случае. Например, в сообщении OnConsoleMessage я вижу ошибку в коде JavaScript — «Ошибка в gwtAdapter: undefined», lineNumber=110, sourceId='file:///workspace/xxxxxx/processes/Contents/Login/js/functions. js», похоже, обратный вызов Java не вызывается из-за некоторых ошибок в коде JavaScript. Убедитесь, что код JavaScript не вызывает ошибок в функции gwtAdapter().   -  person Vladimir    schedule 11.05.2016


Ответы (2)


Вчера TeamDev выпустила версию 6.4 (Chromium v49) для jxBrowser, в которой проблема решена.

person dominic.e    schedule 13.05.2016

У нас недавно была похожая проблема.

Мы нашли такое решение:

  • Сохраняйте ссылку на переданные вами объекты JavascriptBridge в другом месте вашего приложения (например, статическую переменную).

Мы считаем, что причина проблемы заключается в следующем:

  • В какой-то момент объект может быть удален сборщиком мусора. И это когда объект-мост перестает работать.
  • По неизвестной причине JX не хранит ссылку на этот объект, как это обычно делает java, что делает его подходящим для сборки мусора.
  • Сохраняя ссылку в вашем java-приложении, этого не может произойти.
person Frederic Leitenberger    schedule 09.08.2018