我如何解决 java2d 中的 ClassCastException(错误 ID 7172749)
How can i work around the ClassCastException in java2d (Bug-ID 7172749)
我运气不好 java8,
这对其他人来说似乎不是什么大问题,因此 Oracle 不会在 java9.
之前修复它
该错误有 Bug-ID 7172749(另请注意相关和重复的错误)
它只是 一直 在某台 linux 机器上发生。
我在使用 jdk1.8.0_u66.
的 Ubuntu 14.04.3 LTS 上遇到问题
但是,在另一个装有 Ubuntu 12.04.3 LTS 和 same JDK 版本的盒子上,我根本无法重现该问题。
令我困惑的是,这似乎对其他任何人来说都不是一个障碍,所以我想也许我犯了一个特别愚蠢的错误……
我是 运行 Oracle-JDK(与 OpenJDK 相反),因为我们的客户使用相同的版本(尽管在 windows 上)并且我的想法是接近他们的环境。
所以,我的问题是,如何解决这个问题(例如,安装 X11-library xy,使用魔法 -XXjava2dfailsafe 参数启动我的 java-程序,或者沿着这些行)
并加入可以舒适地等待 oracle 解决实际问题的人群?
此致
托比
顺便说一句,我的 stackstrace 看起来像这样:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.awt.image.BufImgSurfaceData cannot be cast to sun.java2d.xr.XRSurfaceData
at sun.java2d.xr.XRPMBlitLoops.cacheToTmpSurface(XRPMBlitLoops.java:145)
at sun.java2d.xr.XrSwToPMBlit.Blit(XRPMBlitLoops.java:353)
at sun.java2d.SurfaceDataProxy.updateSurfaceData(SurfaceDataProxy.java:498)
at sun.java2d.SurfaceDataProxy.replaceData(SurfaceDataProxy.java:455)
at sun.java2d.SurfaceData.getSourceSurfaceData(SurfaceData.java:233)
at sun.java2d.pipe.DrawImage.renderImageCopy(DrawImage.java:566)
at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:67)
at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:1014)
at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:3318)
at sun.awt.image.ImageRepresentation.drawToBufImage(ImageRepresentation.java:813)
at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:1021)
[...]
我找到了解决该问题的解决方法。
简而言之:使用参数-Dsun.java2d.xrender=false
启动JVM。
有了那个选项,我就再也看不到问题了。
背景信息
Bug JDK-7172749 has now recently been fixed with jdk9 build 124 and the bugfix has been backported via JDK-8158068 to jdk8 update 112. You can download the jdk8u112 build preview from here: JDK8 Early Access Releases.
但是,运行这个版本没有解决我的问题。
我遇到错误的情况:我是 运行 jEdit,在我从挂起到 RAM 恢复 Linux 后看到这些 ClassCastException。
这是相同的堆栈跟踪:
10:04:10 [AWT-EventQueue-0] [error] AWT-EventQueue-0: java.lang.ClassCastException: sun.awt.image.BufImgSurfaceData cannot be cast to sun.java2d.xr.XRSurfaceData
10:04:10 [AWT-EventQueue-0] [error] AWT-EventQueue-0: at sun.java2d.xr.XRPMBlitLoops.cacheToTmpSurface(XRPMBlitLoops.java:145)
此异常的影响是,整个 window jEdit 或部分未绘制并保持白色。
查看 patch for the backported bugfix,它实际上修复了另一个 class 中的 ClassCastException,即 sun.java2d.xr.XRRenderer
.
因此,这并没有解决我的问题也就不足为奇了。
另一个 google 搜索显示 bug JDK-6975408 这让我知道系统 属性 sun.java2d.xrender
.
更多搜索:
此选项在 System Properties for Java 2D Technology
中有描述
引用:
xrender
Intended use: To enable the XRender-based Java 2D rendering pipeline for modern X11-based desktops, offering improved graphics performance.
Introduced: Java SE 7
Default value: false
How to use: The pipeline is disabled by default, but may be enabled by setting the command line property -Dsun.java2d.xrender=true
. Older X11 configurations may not be able to support XRender. The verbose form, -Dsun.java2d.xrender=True
, can be used to enable a message to stdout indicating whether the pipeline was actually enabled.
是的,这是一项功能,已添加 Java7:Xrender pipeline now in JDK7 master
和 Java8,现在默认启用:Java8: Xrender Java2D pipeline enabled by default
根据此博客的评论,XRender 管道仅与 Java2D、AWT 和 Swing 相关 - 其他 GUI 框架(JavaFX、SWT 等)无关受影响:
Swing/AWT based application should benefit, SWT/JavaFX/lwjgl/jogl use other codepaths not related to Java2D.
我在发行说明中没有找到任何内容,但在源代码中,很明显,默认情况下启用了 XRender 管道:sun/awt/X11GraphicsEnvironment.java
commit that changed this, was done already in 2011, according to the ticket 它始终与第一个 jdk8 版本一起发布。
我想,我之前没有遇到这个错误的原因是,我可能使用 java7 作为运行时间很长,而 eclipse 不受影响。
再次仔细查看重复的错误报告,已经有一个与堆栈跟踪匹配:
它是 bug JDK-8133723: sun.awt.image.BufImgSurfaceData 无法投射到太阳。java2d.xr.XRSurfaceData - 它真的不是重复的...
但是,重现此错误可能很困难。它仅在挂起到 RAM 周期后出现。
更新 1 - 触发器
该错误是通过使用 xrandr 更改输出显示触发的,例如
xrandr --output eDP1 --auto --output DVI-1-0 --off
将立即引发 ClassCastException。当我在挂起之前关闭显示器时,我假设是挂起-恢复导致的,但这是错误的。
更新 2 - 新 Java 漏洞票
现在有一个新的 java 故障单:JDK-8160328
更新 3 - 修复了 jdk-9-ea-b131
故障单 JDK-8160328 已作为 JDK-8147542 的副本关闭 - 这个已用 修复java 9 的最新 EA 版本(版本 131 及更高版本)。
我可以确认,在使用 xrandr 切换监视器时我不再收到 ClassCastException。
我运气不好 java8,
这对其他人来说似乎不是什么大问题,因此 Oracle 不会在 java9.
之前修复它
该错误有 Bug-ID 7172749(另请注意相关和重复的错误)
它只是 一直 在某台 linux 机器上发生。
我在使用 jdk1.8.0_u66.
的 Ubuntu 14.04.3 LTS 上遇到问题
但是,在另一个装有 Ubuntu 12.04.3 LTS 和 same JDK 版本的盒子上,我根本无法重现该问题。
令我困惑的是,这似乎对其他任何人来说都不是一个障碍,所以我想也许我犯了一个特别愚蠢的错误…… 我是 运行 Oracle-JDK(与 OpenJDK 相反),因为我们的客户使用相同的版本(尽管在 windows 上)并且我的想法是接近他们的环境。
所以,我的问题是,如何解决这个问题(例如,安装 X11-library xy,使用魔法 -XXjava2dfailsafe 参数启动我的 java-程序,或者沿着这些行)
并加入可以舒适地等待 oracle 解决实际问题的人群?
此致 托比
顺便说一句,我的 stackstrace 看起来像这样:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.awt.image.BufImgSurfaceData cannot be cast to sun.java2d.xr.XRSurfaceData
at sun.java2d.xr.XRPMBlitLoops.cacheToTmpSurface(XRPMBlitLoops.java:145)
at sun.java2d.xr.XrSwToPMBlit.Blit(XRPMBlitLoops.java:353)
at sun.java2d.SurfaceDataProxy.updateSurfaceData(SurfaceDataProxy.java:498)
at sun.java2d.SurfaceDataProxy.replaceData(SurfaceDataProxy.java:455)
at sun.java2d.SurfaceData.getSourceSurfaceData(SurfaceData.java:233)
at sun.java2d.pipe.DrawImage.renderImageCopy(DrawImage.java:566)
at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:67)
at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:1014)
at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:3318)
at sun.awt.image.ImageRepresentation.drawToBufImage(ImageRepresentation.java:813)
at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:1021)
[...]
我找到了解决该问题的解决方法。
简而言之:使用参数-Dsun.java2d.xrender=false
启动JVM。
有了那个选项,我就再也看不到问题了。
背景信息
Bug JDK-7172749 has now recently been fixed with jdk9 build 124 and the bugfix has been backported via JDK-8158068 to jdk8 update 112. You can download the jdk8u112 build preview from here: JDK8 Early Access Releases.
但是,运行这个版本没有解决我的问题。
我遇到错误的情况:我是 运行 jEdit,在我从挂起到 RAM 恢复 Linux 后看到这些 ClassCastException。 这是相同的堆栈跟踪:
10:04:10 [AWT-EventQueue-0] [error] AWT-EventQueue-0: java.lang.ClassCastException: sun.awt.image.BufImgSurfaceData cannot be cast to sun.java2d.xr.XRSurfaceData
10:04:10 [AWT-EventQueue-0] [error] AWT-EventQueue-0: at sun.java2d.xr.XRPMBlitLoops.cacheToTmpSurface(XRPMBlitLoops.java:145)
此异常的影响是,整个 window jEdit 或部分未绘制并保持白色。
查看 patch for the backported bugfix,它实际上修复了另一个 class 中的 ClassCastException,即 sun.java2d.xr.XRRenderer
.
因此,这并没有解决我的问题也就不足为奇了。
另一个 google 搜索显示 bug JDK-6975408 这让我知道系统 属性 sun.java2d.xrender
.
更多搜索:
此选项在 System Properties for Java 2D Technology
中有描述引用:
xrender
Intended use: To enable the XRender-based Java 2D rendering pipeline for modern X11-based desktops, offering improved graphics performance.
Introduced: Java SE 7
Default value: false
How to use: The pipeline is disabled by default, but may be enabled by setting the command line property
-Dsun.java2d.xrender=true
. Older X11 configurations may not be able to support XRender. The verbose form,-Dsun.java2d.xrender=True
, can be used to enable a message to stdout indicating whether the pipeline was actually enabled.是的,这是一项功能,已添加 Java7:Xrender pipeline now in JDK7 master
和 Java8,现在默认启用:Java8: Xrender Java2D pipeline enabled by default
根据此博客的评论,XRender 管道仅与 Java2D、AWT 和 Swing 相关 - 其他 GUI 框架(JavaFX、SWT 等)无关受影响:
Swing/AWT based application should benefit, SWT/JavaFX/lwjgl/jogl use other codepaths not related to Java2D.
我在发行说明中没有找到任何内容,但在源代码中,很明显,默认情况下启用了 XRender 管道:sun/awt/X11GraphicsEnvironment.java commit that changed this, was done already in 2011, according to the ticket 它始终与第一个 jdk8 版本一起发布。 我想,我之前没有遇到这个错误的原因是,我可能使用 java7 作为运行时间很长,而 eclipse 不受影响。
再次仔细查看重复的错误报告,已经有一个与堆栈跟踪匹配:
它是 bug JDK-8133723: sun.awt.image.BufImgSurfaceData 无法投射到太阳。java2d.xr.XRSurfaceData - 它真的不是重复的... 但是,重现此错误可能很困难。它仅在挂起到 RAM 周期后出现。
更新 1 - 触发器
该错误是通过使用 xrandr 更改输出显示触发的,例如
xrandr --output eDP1 --auto --output DVI-1-0 --off
将立即引发 ClassCastException。当我在挂起之前关闭显示器时,我假设是挂起-恢复导致的,但这是错误的。
更新 2 - 新 Java 漏洞票
现在有一个新的 java 故障单:JDK-8160328
更新 3 - 修复了 jdk-9-ea-b131
故障单 JDK-8160328 已作为 JDK-8147542 的副本关闭 - 这个已用 修复java 9 的最新 EA 版本(版本 131 及更高版本)。
我可以确认,在使用 xrandr 切换监视器时我不再收到 ClassCastException。