JDK-4252535 : Dr.Watson on Windows NT from simple Swing application.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.2.1,1.2.2
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1999-07-08
  • Updated: 1999-09-15
  • Resolved: 1999-09-15
Related Reports
Duplicate :  
Description

Name: skT88420			Date: 07/08/99


Running the following program will cause a Dr.Watson
access violation.  
I have seen the failure occur in 5 minutes,
and other times it takes over 12 hours so I typically
run this test overnight.
This test program was created in order to get a
simple test case to demonstrate the random 
Dr. Watson failures that we see in a typical
Swing application.
Run this test with -Djava.compiler=NONE
to demonstrate that the problem is in the JVM or AWT runtime.
The seriousness of the bug is born out by considering an attempt
to run the application in an environment in which the application
is used continously all day, which will guareentee a regular
occurrance of a Dr. Watson.  

// ShowFailTest.java ///////////////////////////////////
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;


public class ShowFailTest extends JFrame implements ActionListener
{
	ShowFail	view;
	Container	cont;

	public ShowFailTest()
	{
		super( "ShowFail Test Program" );

		JButton bnRepeat = new JButton( "repeat" );
		bnRepeat.setActionCommand( "repeat" );
		bnRepeat.addActionListener( this );
	
		JButton bnRepeatStop = new JButton( "stop" );
		bnRepeatStop.setActionCommand( "stop" );
		bnRepeatStop.addActionListener( this );
	
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.anchor = GridBagConstraints.WEST;
		gbc.insets = new Insets( 2, 2, 2, 2 );

		JPanel jp = new JPanel();

		JPanel repeatPanel = new JPanel();
		repeatPanel.add( bnRepeat );
		repeatPanel.add( bnRepeatStop );

		cont = getContentPane();
		cont.add( jp, BorderLayout.NORTH );
		cont.add( repeatPanel, BorderLayout.SOUTH );
		
		pack();
		setVisible( true );

	}


	class PerformThread extends Thread {
		boolean	doRepeat = false;
		boolean	willWaitForContinue = false;
		Object	mySignal = new Object();

		PerformThread( boolean argRepeat ) {
			doRepeat = argRepeat;
		}

		public void setRepeat( boolean b ) {
			doRepeat = b;
			if (doRepeat) {
				synchronized( mySignal ) {
					mySignal.notify();
				}
			}
		}

		public void run() {
			int	rs, cnt = 0;
			String	title, msgCount = "<null>";

			if (doRepeat) {
				willWaitForContinue = true;
			}

			while (true) {
			    do {
				if (doRepeat) {
					cnt++;
					msgCount = "Count = " + cnt;
				}

				rs = view.perform( msgCount, msgCount );
				System.out.println( "view.perform returned " + rs );

				if (doRepeat) {
					int w;
					try {
						w = 250;
						System.out.println( "sleep " + w );
						sleep( w );
					} catch (Exception ex) {
						System.out.println( ex );
					}
				}
			    } while (doRepeat);
				if (willWaitForContinue) {
					try {
						System.out.println( "thread waiting for continue..." );
						synchronized( mySignal ) {
							mySignal.wait();
						}
						System.out.println( "thread continueing" );
					} catch( Exception ex ) {
						System.out.println( ex );
					}
				} else {
					break;
				}
			}
		}
	}


	PerformThread repeatWorker = null;


	public void actionPerformed( ActionEvent ae )
	{
		String	id;

		id = ae.getActionCommand();

		if (id.equals("repeat")) {
			if (view == null) {
				view = new ShowFail();
			}
			if (repeatWorker == null) {
				repeatWorker = new PerformThread( true );
				repeatWorker.start();
			} else {
				repeatWorker.setRepeat( true );
			}

		} else if (id.equals("stop")) {
			if (repeatWorker != null) {
				repeatWorker.setRepeat( false );
			}
		}
	}


	public static void main( String args[] )
	{
		try {
		  UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
		} catch (Exception ex) {
		  System.out.println( "got exception " + ex );
		}
		ShowFailTest	test = new ShowFailTest();
		test.setVisible( true );
	}
}

// ShowFail.java /////////////////////////////////////////////

import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.text.*;


public class ShowFail
{
	boolean		initDone = false;
	JFrame		jframe = null;
	JPanel		jp;
	Container 	cont;

	SomeTextArea	ta1, ta2;
	JScrollPane	scrollpane1, scrollpane2;
	JViewport	viewport1, viewport2;

	class SomeTextArea extends JTextArea {

		SomeTextArea( int rows, int columns ) {
			super();
			setLineWrap( true );
			setWrapStyleWord( true );
			setBorder( new EmptyBorder( 4, 4, 1, 0 ) );
			setEditable( false );
			setRequestFocusEnabled( false );
		}
		public boolean isFocusTraversable() {
			return( false );
		}
	}


	public ShowFail() {
		jframe = new JFrame( "ShowFail" );
		jframe.setSize( 500, 400 );
		jframe.setLocation( 0, 0 );

		cont = jframe.getContentPane();

		// text area one
		ta1 = new SomeTextArea( 5, 60 );
		scrollpane1 = new JScrollPane( ta1, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
						JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
		scrollpane1.setPreferredSize( new Dimension( 200, 200 ) );
		viewport1 = scrollpane1.getViewport();

		// text area two
		ta2 = new SomeTextArea( 5, 60 );
		scrollpane2 = new JScrollPane( ta2, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
						JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
		scrollpane2.setPreferredSize( new Dimension( 200, 200 ) );
		viewport2 = scrollpane2.getViewport();


		GridBagLayout	gridbagmain = new GridBagLayout();
		GridBagConstraints gbcmain = new GridBagConstraints();

		jp = new JPanel( gridbagmain );

		gbcmain.weightx = 1;
		gbcmain.weighty = 1;
		gbcmain.gridwidth = 1;
		gbcmain.gridheight = 1;

		GridBagLayout	gridbag = new GridBagLayout();
		GridBagConstraints gbc = new GridBagConstraints();

		gbc.weightx = 1;
		gbc.weighty = 1;
		gbc.gridwidth = 1;
		gbc.insets = new Insets( 0, 2, 0, 0 );

		gbcmain.fill = GridBagConstraints.BOTH;
		gbcmain.anchor = GridBagConstraints.WEST;
		gbcmain.gridx = 0;
		gbcmain.gridy = GridBagConstraints.RELATIVE;
		gbcmain.gridheight = 5;
		gbcmain.weightx = 1;
		gbcmain.weighty = 0.80;
		jp.add( scrollpane1, gbcmain );

		gbcmain.fill = GridBagConstraints.BOTH;
		gbcmain.anchor = GridBagConstraints.WEST;
		gbcmain.gridx = 0;
		gbcmain.gridy = GridBagConstraints.RELATIVE;
		gbcmain.gridheight = 5;
		gbcmain.weightx = 1;
		gbcmain.weighty = 0.80;
		jp.add( scrollpane2, gbcmain );

		jframe.setContentPane( jp );
	}


	void doInit() {
		jframe.setVisible( true );
		initDone = true;
	}


	private void setFields( String t1, String t2 ) {

		ta1.setText( t1 );
		ta2.setText( t2 );

		// position scroll region to textarea 0 position.
		viewport1.setViewPosition( new Point(0,0) );
		viewport2.setViewPosition( new Point(0,0) );

		//jframe.pack();
		jframe.setVisible( true );
		jframe.invalidate();
		jframe.requestFocus();
		jframe.repaint();
	}

	String	arg1, arg2;

	public int perform( String t1, String t2 ) {
		if ( ! initDone ) {
			doInit();
		}
		if (t1 == null) {
			t1 = "";
		}
		if (t2 == null) {
			t2 = "";
		}
		if (SwingUtilities.isEventDispatchThread()) {
			setFields( t1, t2 );
		} else {
			arg1 = t1;
			arg2 = t2;
			SwingUtilities.invokeLater( new Runnable() {
				public void run() {
					setFields( arg1, arg2 );
				}
			});
		}
		return( 0 );
	}

}
	
////////////////////////////////////////////////////
(Review ID: 85313) 
======================================================================

A very similar crash reported from another customer:

Date: Wed, 15 Sep 1999 14:36:19 -0700
From: Paul Cornelius <###@###.###>
X-Accept-Language: en
MIME-Version: 1.0
To: Amy Fowler <###@###.###>
Subject: Re: Random crashes with JDK1.2.x and Windows NT 4.0
Content-Transfer-Encoding: 7bit

Thanks for the reply.  My app does real-time control and data acquisition, so
it involves changing the display in several background threads.  There are
five windows in all but we typically run with only one or two open. The app
uses a lot of JTextFields and JLabels, which are constantly updating on their
own without user intervention.  There are also some JButtons of various types,
but I don't think they are implicated in the problem since the crashes don't
coincide with any particular action by the user.  In addition there are some
custom-drawn UI components that subclass JPanel, but they're fairly simple.

One thing that's somewhat in common with 4252535 is that both programs
generate data in background threads, and both continually update text
components.  4252535 uses JTextAreas while I use mostly JTextFields, but of
course they inherit from the same superclass so it's tempting to conclude that
the problems are related.  In my full application, with all windows open,
there are about 40 JTextFields that get periodically updated.

I also have another application that's a bit larger than the one I described
(~30,000 lines) and it also crashes occasionally to Dr. Watson. It also uses
live updates of JTextFields but has far fewer of them - six to be exact.
Whereas the smaller app (with more JTextFields) crashes every few hours, the
larger one (with few JTextFields) crashes about once every two weeks.

All of this is rather "circumstantial evidence" but if I had to make a wild
guess, I'd suspect a problem with update of text components.

I hope this helps.  Let me know what further information I can supply.

Paul Cornelius

Comments
EVALUATION I can reproduce it with kestrel build. It seems to be an awt bug. I need to make sure of that. ###@###.### 1999-08-10 I think this bug may have been fixed. It seems to be related to shared dc detach problem. Please verify this. ###@###.### 1999-09-15 By the way, the Swing was designed to be single thread library. Multi-thread access may not get correct result, even with proper synchronization. ###@###.### 1999-09-15 Almost certainly a duplicate of 4200425, which is fixed in kestrel. david.mendenhall@eng 1999-09-15
15-09-1999