Как заставить javafx WebView загружать ресурсы из файла jar

Я пытаюсь получить javafx.scene.web.WebView для загрузки ресурсов из файла jar, но он не хочет этого делать и не вызывает никаких значимых ошибок.

Файл jar представляет собой пакет OSGi, в частности пакет приложения (плагина) cytoscape.

Вот мой код: (все работает нормально, если я поставлю https://google.com в качестве URL-адреса).

webView.getEngine().getLoadWorker().exceptionProperty().addListener(new ChangeListener<Throwable>() {
    @Override
    public void changed(ObservableValue<? extends Throwable> ov, Throwable t, Throwable t1) {
        System.out.println("Received exception: "+t1.getMessage() + " " + t1.getClass().getName());
        t1.printStackTrace();
    }
});

webView.getEngine().getLoadWorker().messageProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> ov, String t, String t1) {
        System.out.println("message:" + t1);
    }
});

String url = getClass().getResource("/foo.html").toExternalForm();
webView.getEngine().load(url);
System.out.println("contents:" + new String(getClass().getResourceAsStream("/foo.html").readAllBytes()));   

Это печатает:

message:Loading bundle://202.0:1/foo.html                                                                                                                                        
contents:<p>hello, webview</p>
message:Loading failed
Received exception: Unknown error java.lang.Throwable
    at javafx.web/javafx.scene.web.WebEngine$LoadWorker.describeError(WebEngine.java:1431)
    at javafx.web/javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1370)
    at javafx.web/javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1231)
    at javafx.web/com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:2514)
    at javafx.web/com.sun.webkit.WebPage.fwkFireLoadEvent(WebPage.java:2359)
    at javafx.web/com.sun.webkit.Timer.twkFireTimerEvent(Native Method)
    at javafx.web/com.sun.webkit.Timer.fireTimerEvent(Timer.java:83)
    at javafx.web/com.sun.webkit.Timer.notifyTick(Timer.java:64)
    at javafx.web/javafx.scene.web.WebEngine$PulseTimer.lambda$static$0(WebEngine.java:1192)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)

Я подозреваю, что проблема в том, что WebView не знает об этих bundle: URL. Но я не вижу в WebEngine API, который позволил бы мне реализовать новую схему URL.


person smoofra    schedule 02.06.2020    source источник
comment
Можете ли вы показать полную трассировку стека (t1.printStackTrace())? Возможно, также зарегистрируйте этот URL-адрес?   -  person James_D    schedule 02.06.2020
comment
Хотя это странно. Обратите внимание, поскольку вы продемонстрировали, что можете читать содержимое URL-адреса напрямую, у вас может быть обходной путь через String content = new String(getClass().getResourceAsStream("/foo.html").readAllBytes());, а затем webView.getEngine().loadContent(content); (хотя не знаю, что может случиться с относительными URL-адресами в html ...)   -  person James_D    schedule 03.06.2020
comment
@james_d, да, но я надеялся сделать foo.css следующим. Думаю, я мог бы упаковать все в один HTML в качестве обходного пути   -  person smoofra    schedule 03.06.2020
comment
В документации javadoc для WebEngine указано, что обработка URL-адресов осуществляется через пакет java.net, в котором есть API для пользовательских обработчиков содержимого (но прошло 15 лет с тех пор, как я смотрел на это, и я не помню). Я знаю, что есть плагины Cytoscape, которые используют JavaFX, и, если я правильно помню, WebView был одной из причин для этого, так что кто-то, возможно, решил эту проблему. Я бы отправил сообщение на форум Cytoscape и посмотрел, может ли кто-нибудь помочь.   -  person James_D    schedule 03.06.2020


Ответы (1)


@james_d прав - проблема в том, что URL-адрес, который вы получаете из getResource, представляет собой пакет OSGi: uri, который WebView не умеет читать. Вы можете ознакомиться с нашим кодом CyPlot (https://github.com/RBVI/CyPlot) чтобы увидеть, как мы работали над этим, чтобы прочитать в HTML и Javascript и передать это в веб-браузер Cytoscape.

-- самокат

person Scooter Morris    schedule 04.06.2020
comment
Это правильная ссылка? Похоже, проект почти пуст. - person smoofra; 04.06.2020