JavaFX WebEngine生成StringIndexOutOfBoundsException,有什么不对?

时间:2017-05-13 12:21:00

标签: java javafx javafx-webengine

我有一个使用JavaFX的小实验项目,它有一个按钮和一个WebView。按下按钮时,会加载一个网站:

package sample;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.web.WebView;

public class Controller {
    @FXML private Button theButton;
    @FXML private WebView theWebView;


    @FXML
    protected void loadWebSite(ActionEvent event) {
        theWebView.getEngine().load("https://dashman.tech");
    }
}

当发生这种情况时,我会收到以下错误:

java.lang.StringIndexOutOfBoundsException: String index out of range: 4
    at java.lang.String.substring(String.java:1963)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext.drawString(WCGraphicsPrismContext.java:960)
    at com.sun.webkit.graphics.GraphicsDecoder.decode(GraphicsDecoder.java:290)
    at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:91)
    at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:102)
    at com.sun.webkit.graphics.WCImage.flushRQ(WCImage.java:52)
    at com.sun.javafx.webkit.prism.RTImage.lambda$getPixelBuffer$77(RTImage.java:163)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
    at java.lang.Thread.run(Thread.java:745)
java.lang.StringIndexOutOfBoundsException: String index out of range: 7
    at java.lang.String.substring(String.java:1963)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext.drawString(WCGraphicsPrismContext.java:960)
    at com.sun.webkit.graphics.GraphicsDecoder.decode(GraphicsDecoder.java:290)
    at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:91)
    at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:102)
    at com.sun.webkit.graphics.WCImage.flushRQ(WCImage.java:52)
    at com.sun.javafx.webkit.prism.RTImage.lambda$getPixelBuffer$77(RTImage.java:163)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
    at java.lang.Thread.run(Thread.java:745)
java.lang.StringIndexOutOfBoundsException: String index out of range: 6
    at java.lang.String.substring(String.java:1963)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext.drawString(WCGraphicsPrismContext.java:960)
    at com.sun.webkit.graphics.GraphicsDecoder.decode(GraphicsDecoder.java:290)
    at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:91)
    at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:102)
    at com.sun.webkit.graphics.WCImage.flushRQ(WCImage.java:52)
    at com.sun.javafx.webkit.prism.RTImage.lambda$getPixelBuffer$77(RTImage.java:163)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
    at java.lang.Thread.run(Thread.java:745)

任何想法为什么?我该如何预防呢?该网站似乎正在加载正常。其他网站不会产生这些错误。

1 个答案:

答案 0 :(得分:1)

当我使用jdk1.8.0_131在Mac OSX上测试时,我在堆栈上使用本机方法的不同堆栈时会出现稍微不同的错误:

Exception in thread "JavaFX Application Thread" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
    at java.lang.String.substring(String.java:1963)
    at com.sun.javafx.webkit.prism.WCFontImpl.getGlyphsAndAdvances(WCFontImpl.java:120)
    at com.sun.webkit.network.URLLoader.twkDidReceiveData(Native Method)
    at com.sun.webkit.network.URLLoader.notifyDidReceiveData(URLLoader.java:844)
    at com.sun.webkit.network.URLLoader.lambda$didReceiveData$102(URLLoader.java:819)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

当我将com.sun.javafx.webkit.prism.WCFontImpl的日志记录级别设置为 all 时,我会收到以下信息:

c.sun.javafx.webkit.prism.WCFontImpl - str='ð' (length=2), from=0, to=4, rtl=false
c.sun.javafx.webkit.prism.WCFontImpl - str='ð©' (length=4), from=0, to=7, rtl=false
c.sun.javafx.webkit.prism.WCFontImpl - str='ð' (length=3), from=0, to=6, rtl=false

当我查看字符串时,日志消息中的长度似乎是正确的字符数,但是从和的参数似乎没有考虑到,字符串包含多字节字符。这些错误的值用于子字符串调用,然后导致异常。我无法找到哪个字体在这里制造麻烦。

所以我认为,该网站加载了一些损坏或不正确的字体。浏览器引擎会忽略这些错误,尽管会丢弃堆栈跟踪以及页面工作的原因 - 也许不会显示所需字体的内容。

为什么你有不同的堆栈跟踪?我不确定,这可能是因为您使用的是其他操作系统或不同的Java版本?

我不认为你可以阻止这种情况,只要你对该网站负责并检查使用过的字体。