NullPointerException in invokeLater while running through Java Webstart

前端 未结 5 1536
心在旅途
心在旅途 2020-11-29 06:52

After upgraded from JRE 1.7.0_21 to 1.7.0_25-b15 my application started to throw NullPointerException in SwingUtilities.invokeLater(...) when it is run from Java WebStart. S

5条回答
  •  无人及你
    2020-11-29 07:12

    Here is a workaround for JDK-8019274, packaged in a utility class. For us, invokeAndWait() was still an issue. This example has the existing fix for invokeLater() and a new fix for invokeAndWait().

    Notes:

    • You'll need to include the jnlp.jar in your project.
    • Call init() early in your main() method, before calling invokeLater()
    • Replace all your calls to SwingUtilities invokeLater() and invokeAndWait() with these calls

    (Disclaimer: This is from our product. Some aspects of this solution may not apply to you.)

    public class JreFix {
        private static String badVersionInfo = null;
        private static AppContext awtEventDispatchContext = null;
        private static AppContext mainThreadContext = null;
        private static Boolean isWebStart = null;
        private static BasicService basicService = null;
        private static IntegrationService integrationService = null;
    
        /**
         * Call this early in main().  
         */
        public static void init() {
            if (isWebstart() && isApplicableJvmType()) {
                String javaVersion = System.getProperty("java.version");
    
                if ("1.7.0_25".equals(javaVersion)) {
                    badVersionInfo = "7u25";
                }
                else if ("1.7.0_40".equals(javaVersion)) {
                    badVersionInfo = "7u40";
                }
                else if (javaVersion != null && "1.6.0_51".equals(javaVersion.substring(0,8))) {
                    badVersionInfo = "6u51";
                }
                else if ("javaws-10.25.2.16".equals(System.getProperty("javawebstart.version"))) {
                    badVersionInfo = "Web Start 10.25.2.16";
                }
            }
    
            if (badVersionInfo != null) {
                mainThreadContext = AppContext.getAppContext();
                try {
                    SwingUtilities.invokeAndWait(new Runnable() {
                        public void run() {
                            awtEventDispatchContext = AppContext.getAppContext();
                        }
                    });
                }
                catch (Exception e) {
                    displayErrorAndExit(null);
                }
    
                if (mainThreadContext == null || awtEventDispatchContext == null) {
                     displayErrorAndExit(null);
                }
            }
        }
    
        public static void invokeNowOrLater(Runnable runnable) {
            if (hasAppContextBug()) {
                invokeLaterOnAwtEventDispatchThreadContext(runnable);
            }
            else {
                SwingUtilities.invokeLater(runnable);
            }
        }
    
        public static void invokeNowOrWait(Runnable runnable) {
            if (hasAppContextBug()) {
                fixThreadAppContext(null);
            }
    
            try {
                SwingUtilities.invokeAndWait(runnable);
            } 
            catch (Exception e) {
                // handle it
            }
        }
    
        public static boolean hasAppContextBug() {
            return isJreWithAppContextBug() && AppContext.getAppContext() == null;
        }
    
        public static void invokeLaterOnAwtEventDispatchThreadContext(Runnable runnable) {
            sun.awt.SunToolkit.invokeLaterOnAppContext(awtEventDispatchContext, runnable);
        }
    
        public static void fixThreadAppContext(Component parent) {
            try {
                final Field field = AppContext.class.getDeclaredField("threadGroup2appContext");
                field.setAccessible(true);
                Map threadGroup2appContext = (Map)field.get(null);
                final ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
                threadGroup2appContext.put(currentThreadGroup, mainThreadContext);
            } 
            catch (Exception e) {
                displayErrorAndExit(parent);
            }
    
            if (AppContext.getAppContext() == null) {
                 displayErrorAndExit(parent);
            }
        }
    
        private static boolean isJreWithAppContextBug() {
            return badVersionInfo != null;
        }
    
        private static void displayErrorAndExit(Component parent) {
            JLabel msgLabel = new JLabel("" + 
                    "Our application cannot run using Web Start with this version of Java.

    " + "Java " + badVersionInfo + " contains a bug acknowledged by Oracle (JDK-8019274)."); JOptionPane.showMessageDialog(parent, msgLabel, "Java Version Error", JOptionPane.ERROR_MESSAGE); System.exit(1); } private static boolean isApplicableJvmType() { String vendor = System.getProperty("java.vendor"); String vmName = System.getProperty("java.vm.name"); if (vendor != null && vmName != null) { return vmName.contains("Java HotSpot") && (vendor.equals("Oracle Corporation") || vendor.equals("Sun Microsystems Inc.")); } return false; } private static boolean isWebstart() { if (isWebStart == null) { try { basicService = (BasicService) ServiceManager.lookup("javax.jnlp.BasicService"); isWebStart = true; } catch (UnavailableServiceException e) { isWebStart = false; } try { integrationService = (IntegrationService) ServiceManager.lookup("javax.jnlp.IntegrationService"); } catch (UnavailableServiceException e) { } } return isWebStart; } }

提交回复
热议问题