diff options
author | Emmanuel Puybaret <[email protected]> | 2013-12-07 07:21:24 -0800 |
---|---|---|
committer | Harvey Harrison <[email protected]> | 2013-12-07 07:24:08 -0800 |
commit | 14206478b7a5bf628b59094c92d5727291c7c2bf (patch) | |
tree | d10cd56b27375464243743f9157b482aa758f688 | |
parent | 483b7942ccd2db2d2645ce9b93068a0f9563a379 (diff) |
j3dutils: add workaround for appcontext bug in Java 7 u251.6.0-pre9
As explained here:
http://stackoverflow.com/questions/17223304/appcontext-is-null-from-rmi-thread-with-java-7-update-25
Signed-off-by: Harvey Harrison <[email protected]>
-rw-r--r-- | src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java b/src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java index c3301a9..feee512 100644 --- a/src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java +++ b/src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java @@ -56,6 +56,11 @@ import javax.swing.event.AncestorListener; import com.sun.j3d.exp.swing.impl.AutoOffScreenCanvas3D; +// EP +import java.lang.reflect.Field; +import java.util.Map; +// EP + /** * This class provides a lightweight capability to Java 3D. The component @@ -608,7 +613,7 @@ public class JCanvas3D extends JPanel implements AncestorListener { // to wait for the readback of the off-screen buffer to complete. // The total time is MAX_WAIT_LOOPS * MAX_WAIT_TIME msec. private static final int MAX_WAIT_LOOPS = 5; - private static final long MAX_WAIT_TIME = 100; + private static final long MAX_WAIT_TIME = 10; // EP: Used to be 100; /** * the bufferedImage that will be displayed as the result @@ -659,6 +664,10 @@ public class JCanvas3D extends JPanel implements AncestorListener { */ boolean waitingForSwap; + // EP + Object mainThreadContext; + // EP + /** * Creates a new instance of JCanvas3D. Resize mode is set * to RESIZE_IMMEDIATELY and validation delay to 100ms. @@ -674,6 +683,15 @@ public class JCanvas3D extends JPanel implements AncestorListener { imageReadyBis = false; waitingForSwap = false; addNotifyFlag = false; + + // EP + try { + // Retrieve main thread AppContext instance by reflection + this.mainThreadContext = Class.forName("sun.awt.AppContext").getMethod("getAppContext").invoke(null); + } catch (Throwable ex) { + // Let's consider app context is not necessary for the program + } + // EP } /** @@ -728,6 +746,11 @@ public class JCanvas3D extends JPanel implements AncestorListener { if (false == waitingForSwap) { // System.err.println("repaint " + System.currentTimeMillis()); + + // EP + checkAppContext(); + // EP + this.lwCanvas.repaint(); } else { notify(); @@ -737,6 +760,33 @@ public class JCanvas3D extends JPanel implements AncestorListener { } } + // EP + /** + * Checks that app context is correct. + */ + private void checkAppContext() { + if (this.mainThreadContext != null) { + try { + // Check by reflection that sun.awt.AppContext.getAppContext() doesn't return null + // (required by ImageIO.write() and other JMF internal calls) to apply workaround proposed at + // http://stackoverflow.com/questions/17223304/appcontext-is-null-from-rmi-thread-with-java-7-update-25 + Class<?> appContextClass = Class.forName("sun.awt.AppContext"); + if (appContextClass.getMethod("getAppContext").invoke(null) == null) { + Field field = appContextClass.getDeclaredField("threadGroup2appContext"); + field.setAccessible(true); + Map threadGroup2appContext = (Map)field.get(null); + ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup(); + threadGroup2appContext.put(currentThreadGroup, this.mainThreadContext); + } + } catch (Throwable ex) { + // Let's consider app context is not necessary for the program + } + // Don't need mainThreadContext anymore + this.mainThreadContext = null; + } + } + // EP + /** * Overriden so that the JComponent can access it. * @@ -822,7 +872,9 @@ public class JCanvas3D extends JPanel implements AncestorListener { if (!imageReadyBis && --counter <= 0) { //if i've waited too long for the canvas to be there, let us declare it crashed. - System.err.println("CANVAS CRASHED!!!"); + // EP + // System.err.println("CANVAS CRASHED!!!"); + // EP canvasCrashed = true; return; } |