本文介绍了如何解决无法识别的图像加载器:JavaFX中为null?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序是使用JavaFX用Java 8编写的,它会截取屏幕快照或快照,并且两次生成此错误:

My application, written in Java 8 using JavaFX, takes screenshots, or rather, snapshots, and twice it generated this error:

java.lang.IllegalArgumentException: Unrecognized image loader: null
    at javafx.scene.image.WritableImage.loadTkImage(WritableImage.java:240)
    at javafx.scene.image.WritableImage.access$000(WritableImage.java:46)
    at javafx.scene.image.WritableImage$1.loadTkImage(WritableImage.java:51)
    at javafx.scene.Scene.doSnapshot(Scene.java:1236)
    at javafx.scene.Node.doSnapshot(Node.java:1864)
    at javafx.scene.Node.snapshot(Node.java:1942)

到目前为止,在我的应用程序中,我无法重现它.搜索此问题后,我发现了这一点:

So far, in my application, I wasn't able to reproduce it. Searching for this issue I found this:

https://bugs.openjdk.java.net/browse/JDK-8116783

指向:

https://bugs.openjdk.java.net/browse/JDK-8088198

这似乎是JavaFX中的一个公开错误:如果尺寸大于最大纹理大小,则会从快照引发异常".

It seems to be an open bug in JavaFX: "Exception thrown from snapshot if dimensions are larger than max texture size".

对该错误的描述说,它偶尔会发生.有人知道捕获异常并重试是一种好方法还是解决方法?

The description of the bug says that it happens occasionally. Does anybody know if catching the exception and retrying would be a good way or workaround it?

更新:当我尝试通过使屏幕截图很大来重现此错误时,我遇到了完全不同的错误:

Update: when I tried to reproduce this error by making the screenshot very big, I got a completely different error:

java.lang.NullPointerException
    at com.sun.prism.impl.ps.BaseShaderContext.initLCDBuffer(BaseShaderContext.java:703)
    at com.sun.prism.impl.ps.BaseShaderContext.validateLCDBuffer(BaseShaderContext.java:725)
    at com.sun.prism.impl.ps.BaseShaderGraphics.initLCDSampleRT(BaseShaderGraphics.java:1925)
    at com.sun.prism.impl.ps.BaseShaderGraphics.drawString(BaseShaderGraphics.java:2059)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$10.doPaint(WCGraphicsPrismContext.java:936)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint(WCGraphicsPrismContext.java:1500)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint(WCGraphicsPrismContext.java:1485)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext.drawString(WCGraphicsPrismContext.java:948)
    at com.sun.webkit.graphics.GraphicsDecoder.decode(GraphicsDecoder.java:299)
    at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:92)
    at com.sun.webkit.WebPage.paint2GC(WebPage.java:734)
    at com.sun.webkit.WebPage.paint(WebPage.java:701)
    at com.sun.javafx.sg.prism.web.NGWebView.renderContent(NGWebView.java:96)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
    at com.sun.javafx.tk.quantum.QuantumToolkit$5.draw(QuantumToolkit.java:1393)
    at com.sun.javafx.tk.quantum.QuantumToolkit$5.run(QuantumToolkit.java:1429)
    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:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
    at java.lang.Thread.run(Thread.java:748)

类似地,这是一个根本没有调用触及我的代码的线程.

It similarly is a thread with no call touching my code at all.

推荐答案

TL; DR:

  • 即使使用Oracle JVM,也请参阅: https://wiki.openjdk.java.net/pages/viewpage.action?pageId = 20415996
  • 使用 -Dprism.poolstats = true -Dprism.verbose = true 检查您的maxvram限制并查看您实际消耗了多少vram
  • -Dprism.maxvram = xxxxM 设置为较低的值可能有助于重现该问题
  • -Dprism.maxvram = xxxxM 设置为更高的值可能有助于解决该问题
  • even if using Oracle JVM, see: https://wiki.openjdk.java.net/pages/viewpage.action?pageId=20415996
  • use -Dprism.poolstats=true -Dprism.verbose=true to check your maxvram limit and to see how much vram you actually consume
  • setting -Dprism.maxvram=xxxxM to lower value might help to reproduce the problem
  • setting -Dprism.maxvram=xxxxM to higher value might help to solve the problem

我的案子(针对任何有兴趣的人)

正如上面链接中所建议的那样,我使用了 -Dprism.poolstats = true -Dprism.verbose = true ,并发现maxvram足够高.无论如何,可以肯定的是,我添加了 -Dprism.maxvram = 1024M -Dprism.targetvram = 512M ,但这没有帮助.有足够的内存,但分配失败,并出现以下错误:

As suggested in the link above I used -Dprism.poolstats=true -Dprism.verbose=true and found that maxvram is high enough. Anyway, to be really sure, I added -Dprism.maxvram=1024M -Dprism.targetvram=512M but it didn't help. There was enough memory but the allocation kept failing with the following errors:

D3D Vram Pool: 66.929.834 used (12,5%), 81.273.002 target (15,1%), 536.870.912 max
36 total resources being managed
average resource age is 12,6 frames
0 resources at maximum supported age (0,0%)
5 resources marked permanent (13,9%)
0 resources have had mismatched locks (0,0%)
0 resources locked (0,0%)
31 resources contain interesting data (86,1%)
0 resources disappeared (0,0%)

Growing pool D3D Vram Pool target to 116.658.814
Growing pool D3D Vram Pool target to 131.338.878
Growing pool D3D Vram Pool target to 159.043.730
D3D hresult failed :D3D_ERROR ffffffff8007000e
java.lang.Exception: Stack trace
        at com.sun.prism.d3d.D3DContext.validate(D3DContext.java:133)
        at com.sun.prism.d3d.D3DContext.validatePresent(D3DContext.java:183)
        at com.sun.prism.d3d.D3DRTTexture.readPixels(D3DRTTexture.java:116)
        at com.sun.prism.d3d.D3DRTTexture.readPixels(D3DRTTexture.java:90)
        at com.sun.javafx.tk.quantum.QuantumToolkit$5.run(QuantumToolkit.java:1437)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
        at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
        at java.lang.Thread.run(Unknown Source)
D3D Vram Pool: 109.314.750 used (20,4%), 159.043.730 target (29,6%), 536.870.912 max
37 total resources being managed
average resource age is 13,1 frames
0 resources at maximum supported age (0,0%)
5 resources marked permanent (13,5%)
0 resources have had mismatched locks (0,0%)
0 resources locked (0,0%)
32 resources contain interesting data (86,5%)
0 resources disappeared (0,0%)

2018-07-17 18:05:09 [JavaFX Application Thread] de.apris3.client.ErrorHandler.handle()
   ERROR: : java.lang.IllegalArgumentException: Unrecognized image loader: null
        at javafx.scene.image.WritableImage.loadTkImage(WritableImage.java:240)
        at javafx.scene.image.WritableImage.access$000(WritableImage.java:46)
        at javafx.scene.image.WritableImage$1.loadTkImage(WritableImage.java:51)
        at javafx.scene.Scene.doSnapshot(Scene.java:1236)
        at javafx.scene.Node.doSnapshot(Node.java:1864)
        at javafx.scene.Node.snapshot(Node.java:1942)
        ...
D3D Vram Pool: 112.230.142 used (20,9%), 159.043.730 target (29,6%), 536.870.912 max
40 total resources being managed
average resource age is 13,0 frames
0 resources at maximum supported age (0,0%)
5 resources marked permanent (12,5%)
0 resources have had mismatched locks (0,0%)
0 resources locked (0,0%)
35 resources contain interesting data (87,5%)
0 resources disappeared (0,0%)

很显然,即使限制足够高,JVM也无法分配足够的内存.搜索 D3D hresult失败:D3D_ERROR ffffffff8007000e 显示实际上是Windows错误( https://docs.microsoft.com/zh-cn/windows/desktop/seccrypto/common-hresult-values ):

Obviously, JVM couldn't allocate enough memory even though the limit was high enough. Searching for D3D hresult failed :D3D_ERROR ffffffff8007000e revealed it's actually a Windows error (https://docs.microsoft.com/en-us/windows/desktop/seccrypto/common-hresult-values):

E_OUTOFMEMORY   Failed to allocate necessary memory     0x8007000E 

最后,在检查了设备管理器之后,事实证明客户端已安装了新的图形卡,并且Windows Update更新了驱动程序.

Finally, after checking the device manager, it turned out that the client had installed a new graphic card and Windows Updated screwed the drivers up.

这篇关于如何解决无法识别的图像加载器:JavaFX中为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 10:04