我有幸遭遇java8中的错误,
对于其他任何人来说,这似乎不是一个大问题,因此Oracle不会在java9之前修复它。
这个bug有 错误ID 7172749 (还要注意相关和重复的错误)
它刚刚发生 每时每刻 在某台Linux机器上。
我在使用jdk1.8.0_u66的Ubuntu 14.04.3 LTS上遇到了问题。
但是,在Ubuntu 12.04.3和LTS的另一个盒子上 相同 JDK版本,我无法重现这个问题。
让我感到困惑的是,对于其他任何人来说,这似乎并不是一个显而易见的事情,所以我想也许我正在犯一个特别的转储错误。
我正在运行Oracle-JDK(而不是OpenJDK),因为我们的客户使用相同的版本(尽管在Windows上)并且想法是接近他们的环境。
所以,我的问题是,如何解决这个问题(例如,安装X11-library xy,使用magic -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)
[...]
我想出了一个 解决方法 对于这个问题。
简而言之:使用参数启动JVM -Dsun.java2d.xrender=false
。
有了这个选项,我再也没有看到问题了。
背景资料
该 错误JDK-7172749 现在最近已经修复了jdk9 build 124并且bugfix已经通过后向移植了 JDK-8158068 到jdk8更新112.您可以从这里下载jdk8u112构建预览: JDK8早期版本。
但是,运行此构建并没有解决我的问题。
我的情况,我遇到了错误:我正在运行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)
此异常的效果是,jEdit或部件的整个窗口未绘制并保持白色。
看着 后端错误修复的补丁,它实际上修复了一个不同类的ClassCastException,即in sun.java2d.xr.XRRenderer
。
所以,这并不令人惊讶,这并没有解决我的问题。
另一个谷歌搜索透露 错误JDK-6975408 这让我意识到系统属性 sun.java2d.xrender
。
更多搜索:
此选项在中描述 Java 2D技术的系统属性
引用:
XRENDER
有可能的使用: 为现代基于X11的桌面启用基于XRender的Java 2D渲染管道,提供改进的图形性能。
介绍: Java SE 7
默认值: 假
如何使用: 默认情况下禁用管道,但可以通过设置命令行属性来启用管道 -Dsun.java2d.xrender=true
。较旧的X11配置可能无法支持XRender。冗长的形式, -Dsun.java2d.xrender=True
,可用于启用消息到stdout,指示管道是否实际启用。
是的,这是一个功能,已添加Java7: Xrender管道现在在JDK7 master中
也可以看看 Java SE 7中的增强功能
使用Java8,它现在默认启用: Java8:默认情况下启用Xrender Java2D管道
根据这篇博客的评论,XRender管道仅与Java2D,AWT和Swing相关 - 其他GUI框架(JavaFX,SWT,...)不受影响:
基于Swing / AWT的应用程序应该受益,SWT / JavaFX / lwjgl / jogl使用与Java2D无关的其他代码路径。
我没有在发行说明中找到任何内容,但在源代码中,很明显,XRender管道默认启用: 太阳/ AWT / X11GraphicsEnvironment.java
该 承诺 改变了这种情况,已经在2011年完成了 票 它始终与第一个jdk8版本一起发布。
我想,我之前没有遇到过这个bug的原因是,我可能使用java7作为运行时间很长而且eclipse不受影响。
仔细查看重复的错误报告,已经有一个与堆栈跟踪匹配:
它的 错误JDK-8133723:sun.awt.image.BufImgSurfaceData无法强制转换为sun.java2d.xr.XRSurfaceData - 它真的不是重复的......
但是,重现此错误可能很困难。它只在暂停到RAM周期后出现。
更新1 - 触发器
通过使用xrandr更改输出显示来触发错误,例如
xrandr --output eDP1 --auto --output DVI-1-0 --off
将立即导致ClassCastException。当我在暂停之前插上我的显示器时,我认为,这是暂停 - 恢复造成这种情况,但这是错误的。
更新2 - 新的Java Bug票证
现在有一个新的java bug票证: JDK-8160328
更新3 - 使用jdk-9-ea-b131修复
错误票 JDK-8160328 已被关闭作为副本 JDK-8147542 - 这个已经修好了 针对java 9的最新EA构建 (建立131及以后)。
我可以确认,当用xrandr切换监视器时,我不再获得ClassCastException。