java.lang.NullPointerException thrown from a thread when Applet.start() or Applet.stop() is called


Symptoms

When running an applet in a browser using the Sun JRE, a NullPointerException is thrown from a thread when Applet.start() or Applet.stop() is called. The same applet runs under the Microsoft VM.

Cause

In the Microsoft VM, an applet may be visible immediately after Applet.init() is called but before Applet.start(). Similarly, an applet may still be visible after Applet.stop() but before Applet.destroy().

The Sun JRE implementation is slightly different in terms of applet visibility related to the lifecycle methods, so any applet that relies on the Microsoft VM event sequences may break.

Resolution

Code defensively to ensure the applet is visible before drawing. One way to do this is to test whether the Graphics object is null. For example, suppose the applet has the following methods:

        private Thread paintThread = null;

        public void start()
        {
                if (paintThread == null)
                {
                    paintThread = new Thread(this);
                    paintThread.start();           
                }   
        }

        public void stop()
        {
                if (paintThread != null)
                {
                    paintThread.interrupt();    // Assuming the thread has sufficient                                       // time to be interrupted and stop                                       // drawing before destroy() is called.
                    paintThread = null;
                }
        }

        public void run()
        {
                while (Thread.currentThread().isInterrupted() == false)
                {
                        Graphics g = getGraphics();                   
                        g.drawString("Hello World", 100, 100);   // NullPointerException if                                                      // applet is not visible -
                                                     //
g will be null !
                }
        }

        The code for the run method should be changed to the following:

        public void run()
        {
                while (Thread.currentThread().isInterrupted() == false)
                {
                        Graphics g = getGraphics();                 

                        if (g != null)               // Code defensively!
                            g.drawString("Hello World", 100, 100);  
                }
        }

Related Information

        N/A