Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8033255

NullPointerException in sun.awt.SunToolkit when using EventQueue from RMI-Thread

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version " 1.7.0_25 "
      Java(TM) SE Runtime Environment (build 1.7.0_25-b17)
      Java HotSpot(TM) Client VM (build 23.25-b01, mixed mode, sharing)

      Java Web Start 10.25.2.17


      The same error also happens with the early access release of Java 7u40:
      java version " 1.7.0_40-ea "
      Java(TM) SE Runtime Environment (build 1.7.0_40-ea-b38)
      Java HotSpot(TM) Client VM (build 24.0-b55, mixed mode, sharing)
      Java Web Start 10.40.2.38


      ADDITIONAL OS VERSION INFORMATION :
      Tested on Windows 7 Prof. SP 1 (ver=Microsoft Windows [Version 6.1.7601]) 64-bit

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      I tested with the JREs that are installed together with the JDK, if that matters.
      I used 32-bit JDK/JRE.

      A DESCRIPTION OF THE PROBLEM :
      The problem occurs, if you have a Java Webstart application that acts as an RMI Server. When it receives a RMI call and calls for example
      javax.swing.SwingUtilities.invokeLater(..) from within the RMI thread
      a NullPointerException occurs in class
      sun.awt.SunToolkit.getSystemEventQueueImplPP(...)

      I couldn't write a test case, but at least an example application which reproduces the error.

      RmiWebstartTest.java contains the webstart application. It starts a Swing GUI with a TextArea. After that it starts a RMI server listening on port 3232 with name " rmiServer " in the RMI registry. It implements remote interface " EchoInterface " by printing the received message to the console as well as to the TextArea (which is updated from the EDT thread).
      RmiClient.java contains a commandline application that lookups and calls the RMI server in the webstart application.


      REGRESSION. Last worked in version 7u21

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1.) Put the source files EchoInterface, RmiWebstartTest.java and RmiClient.java into a directory " test " and compile them
      2.) Package the resulting classes into a JAR file named test.jar
      3.) sign the jar file with the jarsigner tool because the webstart application needs all permissions
      4.) put the jar file and the test.jnlp into the same directory
      5.) modify the " codebase " attribute of the jnlp file to match your directory
      6.) open a command prompt and ensure that java.exe and javaws.exe is on your path
      6.) execute " javaws test.jnlp " to start the webstart app
      7.) execute " java -cp test.jar test.RmiClient " to start the commandline app
      8.) the client app sends a message to the RMI Server


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The client app sends the message " Hello World! " to the RMI sever in the webstart application. The String " Got: Hello World! " should be printed on the Webstart console and in the TextArea of the Swing-GUI without any exception.
      ACTUAL -
      The String " Got: Hello World! " is only printed on the Webstart console, the TextArea is not updated. Instead a java.lang.NullPointerException occurs and is printed to the console.
      The commandline client app prints the following stacktrace.


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.NullPointerException
              at sun.awt.SunToolkit.getSystemEventQueueImplPP(SunToolkit.java:1011)
              at sun.awt.SunToolkit.getSystemEventQueueImplPP(SunToolkit.java:1007)
              at sun.awt.SunToolkit.getSystemEventQueueImpl(SunToolkit.java:1002)
              at java.awt.Toolkit.getEventQueue(Toolkit.java:1730)
              at java.awt.EventQueue.invokeLater(EventQueue.java:1217)
              at javax.swing.SwingUtilities.invokeLater(SwingUtilities.java:1290)
              at test.RmiWebstartTest$RmiServer.echo(RmiWebstartTest.java:73)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:606)
              at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
              at sun.rmi.transport.Transport$1.run(Transport.java:177)
              at sun.rmi.transport.Transport$1.run(Transport.java:174)
              at java.security.AccessController.doPrivileged(Native Method)
              at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
              at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
              at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
              at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
              at java.lang.Thread.run(Thread.java:724)
              at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
              at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
              at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:160)
              at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
              at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
              at com.sun.proxy.$Proxy0.echo(Unknown Source)
              at test.RmiClient.callServer(RmiClient.java:20)
              at test.RmiClient.main(RmiClient.java:28)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      contents of RmiWebstartTest.java follows
      -------------------
      package test;
      import java.awt.BorderLayout;
      import java.awt.Container;
      import java.net.InetAddress;
      import java.rmi.RemoteException;
      import java.rmi.registry.LocateRegistry;
      import java.rmi.registry.Registry;

      import javax.swing.JFrame;
      import javax.swing.JTextArea;
      import javax.swing.SwingUtilities;
      import javax.swing.WindowConstants;

      public final class RmiWebstartTest {

          /**
           * Starts a Swing GUI with a TextArea. Then it starts a RMI-Server which appends received
           * messages to the TextArea.
           */
          public static void main(String[] args) throws Exception {

              final JTextArea textArea = new JTextArea( " Waiting for message...
       " , 50, 10);
              SwingUtilities.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      textArea.setLineWrap(true);
                      textArea.setWrapStyleWord(true);
                      JFrame frame = new JFrame( " Java Web Start RMI Test " );
                      frame.setBounds(50, 50, 200, 200);
                      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

                      Container contentPane = frame.getContentPane();
                      contentPane.setLayout(new BorderLayout());
                      contentPane.add(textArea, BorderLayout.CENTER);
                      frame.setVisible(true);
                  }
              });

              String thisAddress;
              try {
                  thisAddress = (InetAddress.getLocalHost()).toString();
              } catch (Exception e) {
                  throw new IllegalStateException( " can't get LocalHost InetAddress. " );
              }
              final int port = 3232;
              System.out.println( " Using host " + thisAddress);
              System.out.println( " Using port " + port);
              final RmiServer server = new RmiServer(textArea, port);
          }

          /**
           * <code>RmiServer</code> registers itself with name " rmiServer " in the local registry.
           */
          public static class RmiServer extends java.rmi.server.UnicastRemoteObject implements
                  EchoInterface {

              private final int thisPort;
              private final Registry registry;
              private final JTextArea textArea;

              public RmiServer(JTextArea aTextArea, int port) throws RemoteException {
                  textArea = aTextArea;
                  thisPort = port;
                  registry = LocateRegistry.createRegistry(thisPort);
                  registry.rebind( " rmiServer " , this);
              }

              @Override
              public void echo(final String clientMessage) throws Exception {
                  final String message = " Got: " + clientMessage + "
       " ;
                  System.out.println(message);
                  try {
                      SwingUtilities.invokeLater(new Runnable() {
                          @Override
                          public void run() {
                              textArea.append(message);
                          }
                      });
                  } catch (Exception thr) {
                      System.err.println(thr);
                      throw thr;
                  }
              }
          }
      }
      -------------
      contents of RmiClient.java follows
      -------------
      package test;

      import java.rmi.RemoteException;
      import java.rmi.registry.LocateRegistry;
      import java.rmi.registry.Registry;


      public final class RmiClient {
          private int thisPort;

          public RmiClient(int port) throws RemoteException {
              thisPort = port;
          }

          public void callServer(String message) {
              System.out.println( " sending " + message + " to server " );
              try {
                  final Registry registry = LocateRegistry.getRegistry(null, thisPort);
                  final EchoInterface server = (EchoInterface) (registry.lookup( " rmiServer " ));
                  server.echo(message);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }

          public static void main(String[] args) throws Exception {
              final RmiClient client = new RmiClient(3232);
              client.callServer( " Hello World! " );
              Thread.sleep(5000L);
              System.out.println( " Exiting ... " );
          }
      }
      ----------------
      contents of EchoInterface.java follows
      ----------------
      package test;

      import java.rmi.Remote;

      /**
       * <code>EchoInterface</code> is the Remote interface.
       */
      public interface EchoInterface extends Remote {

          public void echo(String message) throws Exception;
      }
      --------------
      contents of test.jnlp follows
      --------------
      <?xml version= " 1.0 " encoding= " UTF-8 " ?>
      <jnlp codebase= " file:///D:/workspace/work/Bug " spec= " 1.0+ " >
        <application-desc main-class= " test.RmiWebstartTest " />
        <information>
          <description>Demonstrates a bug when using a RMI server in a Java Webstart application which uses SwingUtilities.invokerLater.</description>
          <description kind= " short " >Webstart RMI Bug</description>
          <homepage href= " index.html " />
          <title>Webstart RMI Bug</title>
          <vendor>Test Corporation</vendor>
        </information>
        <resources>
          <j2se href= " http://java.sun.com/products/autodl/j2se " initial-heap-size= " 128m "
            java-vm-args= " -ea " max-heap-size= " 512m " version= " 1.7.0_25 " />
          <jar href= " test.jar " />
        </resources>
        <security>
          <all-permissions/>
        </security>
      </jnlp>
      ----------------------


      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      no workaround known.

            scfitch Stephen Fitch
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: