JDK-7029995 : NullPointerException in sun.java2d.ScreenUpdateManager.createScreenSurface()
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_7
  • CPU: x86
  • Submitted: 2011-03-22
  • Updated: 2012-03-20
  • Resolved: 2011-04-07
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b130)
Java HotSpot(TM) Client VM (build 21.0-b02, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
A NullPointerException occurs in JDK 7 when calling Container.remove() and the Component.removeNotify() has been overridden to retain the peer object.

This results from the addition, in Java 7, of the line:
    comp.setGraphicsConfiguration(null);
at
    java.awt.Container.remove(Container.java:1209)

REGRESSION.  Last worked in version 6u24

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Please run the test case, ScreenUpdateManagerNPE.main().

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Given test case is expected to run without exception on Java 7.
ACTUAL -
Given test case runs to completion on Java 6.  NPE occurs on Java 7.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at sun.java2d.ScreenUpdateManager.createScreenSurface(ScreenUpdateManager.java:86)
	at sun.java2d.d3d.D3DScreenUpdateManager.createScreenSurface(D3DScreenUpdateManager.java:161)
	at sun.awt.windows.WComponentPeer.createScreenSurface(WComponentPeer.java:424)
	at sun.awt.windows.WComponentPeer.replaceSurfaceData(WComponentPeer.java:448)
	at sun.awt.windows.WComponentPeer.replaceSurfaceData(WComponentPeer.java:416)
	at sun.awt.windows.WComponentPeer.updateGraphicsData(WComponentPeer.java:504)
	at java.awt.Component.updateGraphicsData(Component.java:1144)
	at java.awt.Component.setGraphicsConfiguration(Component.java:1130)
	at java.awt.Canvas.setGraphicsConfiguration(Canvas.java:79)
	at java.awt.Container.remove(Container.java:1209)
	at java.awt.Container.remove(Container.java:1253)
	at javax.swing.JFrame.remove(JFrame.java:585)
	at com.attachmate.bugdemo.ScreenUpdateManagerNPE$3.run(ScreenUpdateManagerNPE.java:45)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:660)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/**
 * Example class.
 */
package com.attachmate.bugdemo;

import javax.swing.*;
import java.awt.*;

public class ScreenUpdateManagerNPE
{
    private static class MyCanvas extends Canvas
    {
        public void removeNotify() {} // retain surface

        public void releaseSurface()
        {
            super.removeNotify();
        }
    }

    private static final long VISIBLE_STEP_DELAY = 1000L;

    public static void main(String[] args) throws InterruptedException
    {
        final JFrame frame = new JFrame("ScreenUpdateManager NPE Demo");
        frame.getContentPane().setBackground(Color.blue);
        frame.setLayout(null);
        frame.setSize(200, 200);

        final MyCanvas canvas = new MyCanvas();
        canvas.setBackground(Color.green);
        canvas.setSize(50, 50);

        SwingUtilities.invokeLater(new Runnable() {public void run() {
            frame.setVisible(true);
        } });

        Thread.sleep(VISIBLE_STEP_DELAY);
        SwingUtilities.invokeLater(new Runnable() {public void run() {
            frame.add(canvas, 0);
        } });

        Thread.sleep(VISIBLE_STEP_DELAY);
        SwingUtilities.invokeLater(new Runnable() {public void run() {
            frame.remove(canvas);    // <-- NPE occurs here
            canvas.releaseSurface();
        } });

        Thread.sleep(VISIBLE_STEP_DELAY);
        System.exit(0);
    }
}

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

Comments
EVALUATION The specification of the Component.removeNotify() method states: ******************************************************************* This method is called by the toolkit internally and should not be called directly by programs. Code overriding this method should call super.removeNotify as the first line of the overriding method. ******************************************************************* The test code violates this specification twice: 1. The overridden removeNotify() doesn't call its super method. 2. The test code calls the removeNotify() method directly. AWT doesn't support such usage. Therefore, this is not a defect in Java. The issue is closed.
07-04-2011

EVALUATION Re-assign to the author of fix for CR 6804747, which introduced mentioned change in Container.java.
07-04-2011