How can i work around the ClassCastException in java2d (Bug-ID 7172749) How can i work around the ClassCastException in java2d (Bug-ID 7172749) linux linux

How can i work around the ClassCastException in java2d (Bug-ID 7172749)


I figured out a workaround for the problem.

In short: Start the JVM with the parameter -Dsun.java2d.xrender=false.

With that option, I didn't see the problem anymore.

Background Info

The 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.

However, running this build didn't fix the problem for me.

My situation, where I experience the bug: I'm running jEdit and I see these ClassCastException after I resume my Linux from suspend-to-RAM.It's the same stacktrace:

10:04:10 [AWT-EventQueue-0] [error] AWT-EventQueue-0: java.lang.ClassCastException: sun.awt.image.BufImgSurfaceData cannot be cast to sun.java2d.xr.XRSurfaceData10:04:10 [AWT-EventQueue-0] [error] AWT-EventQueue-0:  at sun.java2d.xr.XRPMBlitLoops.cacheToTmpSurface(XRPMBlitLoops.java:145)

The effect of this exception is, that the whole window of jEdit or parts are not drawn and stay white.

Looking at the patch for the backported bugfix, it actually fixed a ClassCastException in a different class, namely in sun.java2d.xr.XRRenderer.

So, it's not suprising that this didn't fix my problem.

Another google search revealed bug JDK-6975408 which made me aware of the system property sun.java2d.xrender.

More searching:

  • This option is described in System Properties for Java 2D Technology

    Quote:

    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.

  • Yes, it's a feature, that has been added with Java7: Xrender pipeline now in JDK7 master

    See also Enhancements in Java SE 7

  • And with Java8, it is now enabled by default: Java8: Xrender Java2D pipeline enabled by default

    According to the comments of this blog, the XRender pipeline is relevant only for Java2D, AWT and Swing - other GUI frameworks (JavaFX, SWT, ...) are not affected:

    Swing/AWT based application should benefit, SWT/JavaFX/lwjgl/jogl use other codepaths not related to Java2D.

    I didn't find something in the release notes, but in the source code, it's obvious, that the XRender pipeline is enabled by default: sun/awt/X11GraphicsEnvironment.javaThe commit that changed this, was done already in 2011, according to the ticket it was always on with the first jdk8 release.I guess, the reason, I didn't experience this bug earlier, is, that I probably used java7 as a runtime pretty long and eclipse is not affected.

Having a closer look again on the duplicated bug reports, there is already one, that would match the stacktrace:

It's bug JDK-8133723: sun.awt.image.BufImgSurfaceData cannot be cast to sun.java2d.xr.XRSurfaceData - it's really not a duplicate...However, reproducing this bug might be difficult. It appears only after a suspend-to-RAM cycle.

Update 1 - The trigger

The bug is triggered by changing the output display with xrandr, e.g.

xrandr --output eDP1 --auto --output DVI-1-0 --off

will immediately cause the ClassCastException. As I plug off my monitor before suspend, I assumed, it's the suspend-resume causing this, but that's wrong.

Update 2 - New Java Bug Ticket

There is a new java bug ticket now: JDK-8160328

Update 3 - Fixed with jdk-9-ea-b131

The bug ticket JDK-8160328 has been closed as duplicate of JDK-8147542 - and this one has been fixed with the latest EA build for java 9 (build 131 and later).

I could confirm, that I no longer get the ClassCastException when switching monitors with xrandr.