FULL PRODUCT VERSION :
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
The javax.swing.AbstractButton$ButtonActionPropertyChangeListener class does not have a default no Argument constructor, which is required for serialization, even though the class implements the Serializable interface. When an object of JButton is de-serialized then an exception of type ���javax.swing.AbstractButton$ButtonActionPropertyChangeListener; no valid constructorjava.io.InvalidClassException��� is thrown.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Serialize a new JButton object to file ensuring the JButton object is constructed with an AbstractAction derived object as the argument to the constructor. Then de-serialize the object from file and then an exception is thrown.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No exception should be thrown and the object should have been deserialized from file
ACTUAL -
An exception is thrown and the object isn���t deserialized from file.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
javax.swing.AbstractButton$ButtonActionPropertyChangeListener; no valid constructorjava.io.InvalidClassException: javax.swing.AbstractButton$ButtonActionPropertyChangeListener; no valid constructor
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class JTestApplet extends JApplet
{
	private javax.swing.JPanel jContentPane = null;
	/**
	 * @throws java.awt.HeadlessException
	 */
	public JTestApplet() throws HeadlessException
	{
		super();
	
		init();
	}
	public static void main(String[] args) {
	}
	/**
	 * This method initializes this
	 *
	 * @return void
	 */
	public void init() {
		this.setSize(300, 200);
		this.setContentPane(getJContentPane());
	}
	/**
	 * This method initializes jContentPane
	 *
	 * @return javax.swing.JPanel
	 */
	private javax.swing.JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new javax.swing.JPanel();
			jContentPane.setLayout(new BorderLayout());
		}
		return jContentPane;
	}
	/* (non-Javadoc)
	 * @see java.applet.Applet#start()
	 */
	public void start()
	{
		File serFile = null;
		try
		{
			String strTempDir = System.getProperty("java.io.tmpdir");
				
			serFile = new File(strTempDir + "\\00000001.ser");
	
			////////////////////////////////////////////
			FileOutputStream outStrm = new FileOutputStream(serFile);
			ObjectOutputStream outstr = new ObjectOutputStream(outStrm);
			
			
			////////////////////////////////////////////////////////////////
			
			//create the JButton to serialize with an action for the constructor
			
			JButton button = new JButton(new MyAction("action"));
			
			////////////////////////////////////////////////////////////////
			
			outstr.writeObject(button); //serialize the button
				
			outstr.flush();
			outStrm.close();
			outstr.close();
	
			serFile = null;
						
		}
		catch(Throwable e)
		{
			System.out.println("Serialization " + e.getMessage() + e);
		}
			
	}
	/* (non-Javadoc)
	 * @see java.applet.Applet#stop()
	 */
	public void stop()
	{
		try
		{
			/////////////////////////////////////////////////////////////////////
	
			String strTempDir = System.getProperty("java.io.tmpdir");
				
			File serFile = new File(strTempDir + "\\00000001.ser");
	
			
			if(serFile.exists() == false)
				return;
		
			////////////////////////////////////////////////////////////////////
			////////file exists so we de-serialize it////////////////////////
				
			FileInputStream inStrm = new FileInputStream(serFile);
			ObjectInputStream in = new ObjectInputStream(inStrm);
			
			//now read back the JButton Object
	
			JButton button = (JButton)in.readObject();
				
			in.close();
			inStrm.close();
	
			serFile.delete(); //delete the serialization file
			serFile = null;
													 			
		}
		catch(Throwable e)
		{
			System.out.println("de-Serialization " + e.getMessage() + e);
			e.printStackTrace();
		}
	}
}
class MyAction extends AbstractAction
{
	MyAction(String str)
	{
		super(str);
	}
	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent arg0)
	{
	}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Create the JButton object using the String constructor JButton(String strAction)