使用Java 7 Update 25的rmi线程中的AppContext为null

Rob*_*ago 6 java rmi java-web-start

我们最近从Update 21更新到Java 7 Update 25,并且当从rmi线程调用SwingUtilities.isEventDispatchThread()时,现在遇到空指针异常,因为AppContext.getAppContext()返回null.

显示java.lang.NullPointerException在sun.awt.SunToolkit.getSystemEventQueueImplPP(未知来源)在sun.awt.SunToolkit.getSystemEventQueueImplPP(未知来源)在sun.awt.SunToolkit.getSystemEventQueueImpl(未知来源)在java.awt.Toolkit.getEventQueue(来源不明)在了java.awt.EventQueue.isDispatchThread(来源不明)在javax.swing.SwingUtilities.isEventDispatchThread(来源不明)在......在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect .NativeMethodAccessorImpl.invoke(来源不明)在sun.reflect.DelegatingMethodAccessorImpl.invoke(来源不明)在java.lang.reflect.Method.invoke(来源不明)在sun.rmi.server.UnicastServerRef.dispatch(来源不明)在阳光下.rmi.transport.Transport $ 1.run(未知来源)at sun.rmi.transport.Transport $ 1.在太阳下的sun.rmi.transport.tcp.TCPTransport.handleMessages(未知来源)的sun.rmi.transport.Transport.serviceCall(未知来源)的java.security.AccessController.doPrivileged(本地方法)中运行(未知来源). rmi.transport.tcp.TCPTransport $ ConnectionHandler.run0(来源不明)在sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run(来源不明)在java.util.concurrent.ThreadPoolExecutor.runWorker(来源不明)在爪哇. java.lang.Thread.run上的util.concurrent.ThreadPoolExecutor $ Worker.run(未知来源)(未知来源)run0(来源不明)在sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run(来源不明)在java.util.concurrent.ThreadPoolExecutor.runWorker(来源不明)在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(来自java.lang.Thread.run的未知来源(未知来源)run0(来源不明)在sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run(来源不明)在java.util.concurrent.ThreadPoolExecutor.runWorker(来源不明)在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(来自java.lang.Thread.run的未知来源(未知来源)

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

还有其他人遇到过这个吗?有关AppContext的最新更新中有什么变化的想法吗?

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

dig*_*ity 0

这不是最终答案,但它是一种对我有用的解决方法。

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

  AppContext evtContext; //field

  SwingUtilities.invokeLater(new Runnable() {
      public void run() {
          evtContext = AppContext.getAppContext();
      }
  });
Run Code Online (Sandbox Code Playgroud)

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

希望Oracle尽快提供JRE 1.7.0.u25的补丁来解决这个问题。

- 此解决方法是根据此处guruman评论中的建议提出的。