首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Java7Update 25的AppContext线程为null

使用Java7Update 25的AppContext线程为null
EN

Stack Overflow用户
提问于 2013-06-20 20:35:42
回答 3查看 3.6K关注 0票数 7

我们最近从更新21更新到Java7Update 25,当从rmi线程调用SwingUtilities.isEventDispatchThread()时,出现了空指针异常,因为AppContext.getAppContext()正在返回null。

.#en2#=‘#en2#1’>( sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown来源))( sun.awt.SunToolkit.getSystemEventQueueImpl(Unknown来源)在java.awt.Toolkit.getEventQueue(未知来源)在java.awt.EventQueue.isDispatchThread(不明来源)在.(在sun.reflect.NativeMethodAccessorImpl.invoke0(Native ( sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)在java.lang.reflect.Method.invoke(未知来源)在Sun.rmi.transport.transport.rmi.transport.transport$1(未知来源)在sun.rmi.transport.transport.rmi.transport.transport.rmi.transport.transport1.run(未知来源) java.security.AccessController.doPrivileged(Native方法)在sun.rmi.transport.Transport.serviceCall(Unknown源)在sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown源)在sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown源)在sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown源)在java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown源)在java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown源)在java.lang.Thread.run(未知源)

此错误仅在web启动时出现,当我们通过IDE运行应用程序时,它是很好的。

还有其他人碰到这个吗?知道AppContext的最新更新中发生了什么变化吗?

似乎其他人在更新后与AppContext有一些相关的问题:https://forums.oracle.com/message/11077767#11077767

EN

回答 3

Stack Overflow用户

发布于 2013-08-01 14:42:48

我在运行Java3D时遇到了与相同的问题。我找到了另一个解决办法。您必须准备好自己的InvokeLaterProcessor和可运行的队列。它必须扩展线程和获取ups运行表,并在run方法中处理它们:

代码语言:javascript
复制
public class InvokeLaterProcessor extends Thread {

  private BlockingQueue<Runnable> queue=new ArrayBlockingQueue<Runnable>(1);

  public InvokeLaterProcessor(String name) {
    super(name);
  }

  public void invokeLater(Runnable runnable) {
    try {
      queue.put(runnable);
    } catch (InterruptedException ex) {
      log.warn("invokeLater interrupted");
    }
  }

  public void run() {
    Runnable runnable=null;
    do {
      try {
        runnable = queue.take();
        SwingUtilities.invokeLater(runnable);
      } catch (InterruptedException ex) {
        runnable=null;
      }
    } while(runnable!=null);
  }
}

所要做的就是在某个类的静态中创建它,这个类是在主线程中创建的:

代码语言:javascript
复制
static {
  invokeLaterProcessor=new InvokeLaterProcessor("MyInvokeLater");
  invokeLaterProcessor.start();
}

并通过以下代码处理可运行项:

代码语言:javascript
复制
invokeLaterProcessor.invokeLater(runnable);

你不需要专利

代码语言:javascript
复制
sun.awt.SunToolkit.invokeLaterOnAppContext(evtContext, rn)
票数 1
EN

Stack Overflow用户

发布于 2013-06-25 15:39:08

这不是一个最终的答案,但它是一个解决办法,对我有效。

应用程序需要将当前的AppContext保存在EVT中:

代码语言:javascript
复制
  AppContext evtContext; //field

  SwingUtilities.invokeLater(new Runnable() {
      public void run() {
          evtContext = AppContext.getAppContext();
      }
  });

然后,必须将来自RMI线程的所有对SwingUtilities.invokeLater(..)的调用替换为使用sun.awt.SunToolkit.invokeLaterOnAppContext(..,..)的自定义invokeLater2(Runnable rn)方法,例如:

代码语言:javascript
复制
void invokeLater2(Runnable rn) {
    if (AppContext.getAppContext() == null) {
        logger.warning("AppContext is null, using EVT AppContext"
          + " through SunToolKit");
        sun.awt.SunToolkit.invokeLaterOnAppContext(evtContext, rn);
    } else {
        SwingUtilities.invokeLater(rn);
    }
}

不幸的是,所有对SwingUtilities.invokeLater(..)的调用必须替换RMI线程,程序现在依赖于内部的Sun专有API。

我希望Oracle不久将为JRE 1.7.0.u 25提供补丁来解决这个问题。

--这一解决办法是根据gurumanhere评论中的建议提出的。

票数 0
EN

Stack Overflow用户

发布于 2013-09-27 15:12:26

下面是JDK-8019274的一个解决方案,打包在一个实用程序类中。

对我们来说,invokeAndWait()是个大问题。此示例具有invokeLater()的现有修复程序和invokeAndWait()的新修复程序。

备注:

  • 你需要jnlp.jar
  • 在调用init()之前,先在main()方法中调用invokeLater()
  • 用以下调用替换对invokeLater()invokeAndWait()的所有调用

(免责声明:这是我们的产品。此解决方案的某些方面可能不适用于您。)

代码语言:javascript
复制
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<ThreadGroup, AppContext> threadGroup2appContext = (Map<ThreadGroup, AppContext>)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("<html>" + 
                "Our application cannot run using <b>Web Start</b> with this version of Java.<p><p>" +
                "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;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17223304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档