JDK-8043393 : NullPointerException and no event received when clipboard data flavor changes
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7u55,8u5,9
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2014-05-09
  • Updated: 2015-10-13
  • Resolved: 2015-02-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u60Fixed 9 b56Fixed
Description
FULL PRODUCT VERSION :
Java Plug-in 10.55.2.13
Using JRE version 1.7.0_55-b13 Java HotSpot(TM) Client VM

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
If an applet adds a FlavorListener to the system clipboard and the data type changes, the listener does not receive a FlavorEvent on the change, and a NullPointerException is thrown from java.awt.datatransfer.SystemFlavorMap.getDefaultFlavorMap.

Our product selectively enables/disables several Edit menu commands based on the type of data on the clipboard. When this problem occurs, our applet does not receive notification that the clipboard data has changed, so we cannot enable the clipboard commands, such as Edit:Paste, essentially making the clipboard data unavailable to our applet. This affects our customers who have thousands of data entry workers who need to be able to paste the data they just copied to the clipboard from another application.

REGRESSION.  Last worked in version 7u51

ADDITIONAL REGRESSION INFORMATION: 
java version "1.7.0_55"
Java(TM) SE Runtime Environment (build 1.7.0_55-b13)
Java HotSpot(TM) Client VM (build 24.55-b03, mixed mode, sharing)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a Java applet that adds a FlavorListener to the system clipboard. 
2. Create an HTML page to run the applet in a browser. 
3. Before launching the browser, copy an image to the clipboard. On Windows, you can just press Print Screen.
4. Open a browser and load the HTML page with the test applet.
5. Open a text editor and enter some text (you can also just open the Java console).
6. Make a text selection in the editor.
7. Copy the text selection to the clipboard.

Copying the text selection to the clipboard should result in the flavor listener receiving an event of the changed data flavor, but instead, the Java console shows a NullPointerException from java.awt.datatransfer.SystemFlavorMap.getDefaultFlavorMap. The data is successfully placed on the clipboard, though.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should receive a FlavorChange event when the clipboard data type changes, and no exception should occur.
ACTUAL -
No FlavorChange event is received when the clipboard data type changes. 

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
	at java.awt.datatransfer.SystemFlavorMap.getDefaultFlavorMap(Unknown Source)
	at sun.awt.datatransfer.SunClipboard.getDefaultFlavorTable(Unknown Source)
	at sun.awt.datatransfer.SunClipboard.formatArrayAsDataFlavorSet(Unknown Source)
	at sun.awt.datatransfer.SunClipboard.checkChange(Unknown Source)
	at sun.awt.windows.WClipboard.handleContentsChanged(Unknown Source)
	at sun.awt.windows.WToolkit.eventLoop(Native Method)
	at sun.awt.windows.WToolkit.run(Unknown Source)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.applet.Applet;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class CopyTest extends Applet implements ActionListener, FlavorListener {
	private Clipboard mClipboard;

	public void start() {
		initClipboardListener();
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
		JButton button = new JButton( "Copy Stuff" );
		frame.add( button );
		button.addActionListener( this );
		frame.setSize( 100, 100 );
		frame.setVisible( true );
	}

	public void actionPerformed( ActionEvent e ) {
		Transferable transferable = new StringSelection( "sample text\nsample text\nsample text" );
		Toolkit.getDefaultToolkit().getSystemClipboard().setContents( transferable, null );
	}

	private void initClipboardListener() {
		mClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		mClipboard.addFlavorListener( this );
		System.out.println( "Available data flavors at init..." );
		reportFlavors();
	}

	private void reportFlavors() {
		DataFlavor[] flavors = mClipboard.getAvailableDataFlavors();
		for( DataFlavor flavor : flavors ) {
			System.out.println("Mime type: " + flavor.getMimeType() );
		}
	}

	public void flavorsChanged( FlavorEvent e ) {
		System.out.println( "Received flavorsChanged event: " + e.toString() );
		reportFlavors();
	}
}

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


Comments
needs to be fixed in 7u also
27-05-2014

This is a regression of the security fix JDK-8030679. After that fix SFM is stored per AppContext, so we cannot use it on the TK thread.
20-05-2014

Test applet. 1. Compile CopyTestApplet.java. javac CopyTestApplet.java 2. Modify all-manifest.mf so that it uses the correct Codebase attribute. 3. Create jar file: jar c0mf all-manifest.mf CopyTestApplet.jar CopyTestApplet.class 4. Sign the jar file. 5. Deploy .jar, .jnlp, and .html files to a webserver. 6. Start the applet from the webserver.
19-05-2014