Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4030718
Votes 217
Synopsis A program which calls Toolkit.getDefaultToolkit() won't terminate.
Category java:classes_awt
Reported Against 1.1 , 1.2 , 1.1.1 , 1.1.2 , 1.1.3 , 1.1.4 , 1.1.5 , 1.1.6 , 1.2.1 , 1.2.2 , 1.2rc1 , 1.1beta3 , 1.2beta2 , 1.2beta3 , ladybird , kestrel-rc1 , kestrel-rc2
Release Fixed 1.4(merlin-beta)
State 10-Fix Delivered, request for enhancement
Priority: 3-Medium
Related Bugs 4014091 , 4031168 , 4031334 , 4038690 , 4072987 , 4094071 , 4103350 , 4114597 , 4152761 , 4196724 , 4243784 , 4272445 , 4291432 , 4320219 , 4378087 , 4403762 , 4495767 , 4648733 , 4701990 , 4844504 , 4670707
Submit Date 06-FEB-1997
Description


A program which calls the static method getDefaultToolkit()in
class Toolkit won't terminate. The following is a simplest
java source code for this bug.

import java.awt.*;                                                          
class Test {                                    
    public static void main(String[] args) { 
        Toolkit.getDefaultToolkit();            
    }                        
}         

After starting this program, it should return to OS. However,
it hangs there forever.

I use Window 95. I have tried this program on several different
machines, e.g, standalone ones and network-attached ones, the 
problem is the same.                                                                                                                                            

======================================================================




When java.awt.SystemColor is loaded, it calls Toolkit.getDefaultToolkit(), which
creates two AWT threads.  These threads never stop, and they are not daemon
threads, so the program hangs.  

The following code demonstrates this problem: 

public class SimplCon {
	public SimplCon() {
	}

    static public void main(String args[]) {
        java.awt.Color color = java.awt.SystemColor.window;
    }
}


Note: I have reproduced this problem on a Windows 98 and NT 4.0
machine. It only happens when you use JDK 1.2. It works fine in JDK 1.1.7A.
======================================================================




The AWT threads are *still* not Daemon threads (reported as bug 4030718).
I have presented Sun with a fix for this, which they've had for 7 months.
It's not that the problem is not fixable - so how come no-one has even
evaluated the bug/fix? The report shows up as useless.
(Review ID: 84317)
======================================================================




java version "1.3.0rc2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0rc2-Y)
Java HotSpot(TM) Client VM (build 1.3.0rc2-Y, interpreted mode)

In developing a system which needs to shutdown the grapics environment, I have
found that it is impossible to cleanly close down the awt. The natively
implemented  event loop thread never checks for Java exceptions or any other
exit condition, and as Thread.stop() is now deprecated, it is impossible to
cleanly bring down the display. Here is the excerpt from awt_Motif.c as it
stands - the possiblity of exitting has been considered by the authors, but not
implemented...

...
    /*
     * ACTUALLY PROCESS EVENTS
     */
    
    while(True) {
        ...
	waitForEvents(env, fdXPipe, AWT_READPIPE);
        ...
    } /* while(True) */

    /* If we ever exit the loop, must unlock the toolkit */
...
(Review ID: 103193)
======================================================================
Work Around




Call System.exit() when it is time to shut down the app.
(Review ID: 97019)
======================================================================
Evaluation
Commit for Kestrel.
 xxxxx@xxxxx  1999-06-22

Any fix which involves changing the EventDispatchThread, PostEventQueue, and
Toolkit threads to daemon suffers from a major design problem.

Recall that a new, child thread inherits the daemon status of its parent
thread. By making the EventDispatchThread daemon, we would change the deafult
daemon state of all threads spawned by client code in event handlers. This
is a fairly common thing to do (e.g., Swing worker threads). Previously, 
daemon-ness didn't matter in an AWT application, because the app would never
exit anyways. If this bug were fixed, it definitely would matter. That's okay, 
as long as the default for client code threads is non-daemon. Changing this
default breaks the class of applications which relies on the current 
default daemon state. It is unlikely that every developer has been careful 
enough to set the daemon status of all of their threads explicitly. 

We are continuing to consider  xxxxx  options, including minor API changes, more
complicated fixes, and command-line switches.
 xxxxx@xxxxx  1999-09-10


Customer indicates that their product will ship before Kestrel is released.  
It appears that more substantial changes are necessary to address this 
issue correctly.  We will continue to investigate this for Merlin.  
 xxxxx@xxxxx  1999-10-05


An xxxxx  report that is similar: 4291432 should also be addressed for Merlin.  
 xxxxx@xxxxx  1999-11-16


I am recategorizing this as an RFE, since it is a request for a rearchitecture 
of the AWT, and requires new public APIs.  We have committed to fix this in Merlin.  
 xxxxx@xxxxx  2000-03-08

Apparently, this fix was broken late in Merlin.  4515058 has been filed 
about it.  It is probably too late to fix the problem in Merlin, but we 
will try to fix it as soon as we can.  
 xxxxx@xxxxx  2001-11-09

No, I'm wrong.  It isn't broken.  We just found one case that doesn't exit.  
All the  xxxxx  tests I tried exit just fine.  
 xxxxx@xxxxx  2001-11-15

The solution is 
1) to make the toolkit thread daemon and 
2) to start an AWT event dispatch thread only when the first java event appears 
   in its associated event queue and 
3) to stop all the event dispatch threads when all three conditions become true:
      1. There are no displayable AWT or Swing components.
      2. There are no events in the native event queue.
      3. There are no events in java event queues.
When all the event dispatch threads are terminated, the VM will exit
if there are no  xxxxx  alive non-daemon threads.

This solution implies that normally if an application uses AWT, the
only legal cases for VM to not terminate are as follows:
1. There is an alive non-daemon thread that doesn't belong to AWT
   (see Thread.isAlive() and Thread.isDaemon()). 
2. There is a displayable component (see Component.isDisplayable()).
3. An AWT event is processed on one of AWT event dispatch threads.

To write an AWT application that will terminate without System.exit(),
one should do the following:
1. Stop all non-daemon threads that the application has started.
2. Make all components undisplayable.
3. Make sure that the application doesn't continuously post synthetic
   AWT events to the AWT event queue or that it doesn't post an AWT event
   which processing cannot complete (e.g. an ActiveEvent that
   starts an infinite loop in its dispatch() method). 

 xxxxx@xxxxx 

 xxxxx@xxxxx  2002-04-15
Comments
  
  Include a link with my name & email   

Submitted On 08-JUL-1998
gonedu
The same problem appeared on SGI computers running IRIX6.4 when the java
application is launched from "cron", but not when it is launched from
"at"...


Submitted On 28-JUL-1998
ktohg
I experienced the same (exacly) on a Linux 2.0.30 box
tried every thing. however I did find something else
if the main method calls System.exit() then program terminates
HOWEVER ALL (I belive) methods that are part of the toolkit are not executed!
ex.
class Test {
	public static void main(String[] argv){
		System.out.println("setting a to Toolkit now");
		java.awt.Toolkit a = java.awt.Toolkit.getDefaultToolkit();
		System.out.println("Done. now beeping");
		a.beep();
		System.out.println("opps! Did I beep?");
//		System.exit(0); // coment to freeze uncoment to disable beep!
	}
}
::sigh::


Submitted On 17-NOV-1998
bhiggs
I note that this bug was submitted on Feb 6, 1997, 
and to date has no workaround, no evaluation, and
a state of "In progress, bug".  Also, there are 26
votes for it to be fixed.
I realize that things are busy at JavaSoft, but 
isn't nearly 22 months a pretty long time with no
action?


Submitted On 02-DEC-1998
javagroup
An other solution could be:
Toolkit has a static method to stop the 
underlaying thread.


Submitted On 19-DEC-1998
Massey
Impact of this Bug: 1. Nullifies the "automatic threading management
feature". 2. Denies existence of the "Java desktop". 3. This
makes every AWT application "badly behaved".


Submitted On 17-MAR-1999
os7man
I too stumbled on this bug.  I'm on w95.
The following simple program, when java'd from
DOS box, never returns.  (Did it ever return ?
No, it never returned...)
import java.awt.TextArea;
class goaway
{
static void main (String foo[])
{
TextArea t = new TextArea (500, 100);
t = null;
}
}
QUESITON:  I notice that several bugs are marked
as "duplicate of this one" .  One would hope that
such duplication causes effective upping of the
votes, since it indicates that people are tripping
in different ways.  Is this true ?

I've heard some people suggest the use of
System.exit in order to work around the bug.
The reason I DON'T want to use that solution, is
that System.exit is PRIVILEGED and hence causes
security failures on user's systems.
To avoid the security problems, I want my program
to merely return from all its methods (i.e. unwind
the stack) instead of using System.exit.
Please feel free to send me email with your
feedback on all of this.  Thanks.  /Eric
os7man@mediaone.net







Submitted On 07-MAY-1999
nfiedler
Agreed, this is rather annoying. It would be handy
to be able to make a beep using the Toolkit, but if
it means the app won't shutdown normally, then
forget it.
Please fix this.


Submitted On 30-MAY-1999
antoan
I faced the same problem. A fix will be appreciated.
It is working under NT jdk1.1.7,
but not under Sun jdk1.1.7_7
mailto:antoan@amsnet.com


Submitted On 29-JUN-1999
asb1002
It is encouraging to see that this bug has finally been evaluated (on
1999-06-22)
and that it will be a committed fix for 'Kestrel', whatever that is. A quick
search
indicates that it is a number of feature extensions for JavaDoc (from the
JavaOne slides on here)
and that it will be available 2000 Q1.
It would be nice if a fix could be applied sooner for the 1.1 (and even 1.2)
environments,
particularly as the principle of the fix, and the fix for 1.1 has been
available
since December 1998.


Submitted On 10-SEP-1999
asb1002
Sun have evaluated the fix, and decided not to apply it. Their arguments for
this is that it causes a small discrepancy between JDk1.1/2 and 1.3.
This discrepancy is that any Threads launched via the AWT thread (e.g. in
response to an actionPerformed or some other suitable widget) will be cretaed
as Daemon threads instead of non-Daemon threads.
For the average programmer/application, this distinction is irrelevant. The fix
is clean, lightweight, and does not cause any performance degredation when
applied.
The move to a new level of JDK - 1.3 - is the time to make such changes. Please
vote for this fix to be applied!


Submitted On 27-SEP-1999
grafj
If breaking code depending on defult thread demon state is really a
problem, as stated in evaluation above  (xxxxx@xxxxx 1999-09-10), 
this could be fixed by extending the Thread API. 
Add a (private) field boolean childDefaultDemonState and methods 
that set and get these. The meaning of these should be clear from
the name. Then apply the fix proposed by alex blewitt above (ie make 
the system threads demons), but use the new API to make them 
create non-demon childs per default.
The soloution might rightfully be considered a kludge, but if it 
fixes the bug in an acceptable way i'd say its ok.


Submitted On 30-SEP-1999
asb1002
One obvious point is that it is also a bug that any Daemon threads created by
the AWT are also non-Daemon.
As a simple case, consider an applet that animates a JugglingDuke image. There
may well be start() and stop() buttons associated with the applet that start
and stop a thread:
public void start() {
  myThread = new Thread(this);
  myThread.start();
}
public void stop() {
  if (myThread != null) {
    myThread.stop(); // or interrupt()
    myThread == null;
  }
}
Now consider the case where the user is viewing the applet in some kind of
HTML-editor, written in Java. The user looks at the page, starts the Applet
juggling, and then decides to close the HTML editor. 
If the thread created by the AWT (assuming this bug was fixed) was non-Daemon,
then this could execute for ever, continuously animating the thread whilst the
application is waiting to terminate 'nicely'.
Although it may be an application issue that does not 'stop' the applet, it is
clear that it may cause problems. If there were an Applet, which when started
(possibly by the AWT thread/button push) created a new Thread (using the
default state) created a Thread to animate e.g. ticker/scrolling text animation,
 again the program would not die due to a permanent animating thread.
In my opinion, the fact that the Threads are created non-Daemon by the AWT is
also a bug, and should 4030718 be fixed but creating child threads as
non-Daemon, I would submit that as an associated bug report.
Note that it is possible, should programmers require, to create a Thread which
is non-Daemon from a button push. However, the sensible default is for Threads
which are created by the AWT to also be Daemon as well. This avoids any
problems with hacks to the Thread class, and means that the current suggested
bugfix will work.
In response to the comment "It is unlikely that ever programmer has been
careful enough to set the Daemon status explicitly" - in most cases, such
threads are likely to serve the purpose of Daemon threads (e.g. animating,
connecting to a Socket for updates, drawing routines etc.). Even the Swing
threads are not an issue - the idea is to make such threads Daemon after all,
so that when there are no visible windows/events the JVM will terminate nicely.
Lastly, I feel that there are in fact no applications which require the
existance of a thread after the last window has closed. All applications that I
have seen have code similar to:
public void windowClosing(WindowEvent e) {
  System.exit(0);
}
For applications like this, there is no way any thread - Daemon or otherwise -
can execute after the window has been closed.
I invite Sun to actually find a real application that does not have such a
WindowExiter System.exit() call, which requires a thread to execute after the
windows are not present. I then invite them to show that this application that
they find will be affected with a change.
Alex Blewitt.


Submitted On 30-SEP-1999
asb1002
NB: The 'design problem' listed above is an accurate observation of the issue.
However, the design problem was converting the AWT thread to non-Daemon (and
sub-Threads) in the first place; the fact that this fix changes not only the
AWT bug, but also generated child threads is a *fix* to a major design problem,
not a major design problem in itself.


Submitted On 30-SEP-1999
asb1002
NB: The 'design problem' listed above is an accurate observation of the issue.
However, the design problem was converting the AWT thread to non-Daemon (and
sub-Threads) in the first place; the fact that this fix changes not only the
AWT bug, but also generated child threads is a *fix* to a major design problem,
not a major design problem in itself.


Submitted On 30-SEP-1999
asb1002
Apologies for sending the last comment twice; due to a problem with the
browser. Can someone (from Sun) remove the above duplicate?


Submitted On 16-NOV-1999
richardrussell
Another possible fix (for Sun): enable the user to create or get a reference to
the AWT thread, and enable them to set a particular object as the primary
application object (With say SwingUtilities.setPrimaryOject(this) ). Keep a
weak reference to this Object in the AWT thread, and when this object has no
other references, then it's time to kill that thread, and possibly exit the
JVM...
PS This bug is a REALLY IMPORTANT ONE!


Submitted On 28-MAY-2000
gaillard
Ah, I see this bug is marked "fixed", but the example code still hangs forever
in 1.3.0.  What was the 'fix', exactly?


Submitted On 02-JUN-2000
shauhwenma
I have the same question.... I saw the  state is "fixed" but
I still have the same
"no return" problem with JAVA1.2 on Solaris 5.8

What is SUN's answer ????


Submitted On 04-JUL-2000
MartDesruisseaux
It is wrote "Release fixed: non-public release". Just wait 
a litle bit. Evaluation said it should be fixed for Merlin.


Submitted On 03-DEC-2000
jredpath
Is there a work around this? I want to do

Toolkit.getDefaultTookit().beep();

to make a sound at the end of the application, but hangs (main does not
finish). I tried a System.exit(0); right after it, but then no sound.


Submitted On 17-FEB-2001
nerius
PEOPLE:
I have a workaround for this bug; the workaround will work
on all jvms that i have tested except for the later java 1.1
jvms (1.1.5 thru 1.1.8).
In particular, the workaround works on 1.2.2 and 1.3.x. (It
even works on 1.0.2 !)
A discussion of the workaround is here:
http://www.blockout.net/javabug4030718/


Submitted On 27-APR-2001
steveamos
Still not working in Symantics EE4.0 using JDK1.2.2. S 
simple consol application just hangs. please fix...


Submitted On 22-JAN-2002
abnormal
I'm using jdk1.3.1_01 under windows 2000, and I still see 
this problem..


Submitted On 06-MAR-2002
anthony_beaty
Me too.


Submitted On 17-MAY-2002
nethi
After spending couple of hours trying to find a solution to 
the same problem, here is what I came up with as a work-
around. Force the event dispatcher to be a daemon thread by 
creating a dummy daemon thread as follows before you do 
anything useful with AWT in your app:

Thread td = new Thread()  {
   public void run()  
   {
        javax.swing.JFrame frame = new javax.swing.JFrame
("dummy")	;  
        frame.pack() ;
        frame.setVisible(true) ;
        //If you donot want this dummy frame to appear on 
screen, set it's location to offscreen 
        frame.show() ;
        frame.dispose() ;
   }
} ;
td.setDaemon(true) ;
td.start() ;
td.join() ;

//Now you are ready to other useful stuff. Since AWT 
threads are now daemon threads, you donot have to worry 
about calling system.exit(0).

This seems to do the job for me.

regards
Nethi


Submitted On 07-JAN-2003
mittendo
Using jdk 1.4.1:

Program terminates if I use a JFrame:

JFrame f = new JFrame();
f.setVisible(true);
f.setVisible(false);
f.dispose();

The aequivalent code using a JWindow or Window still doesn't terminate without System.exit()


Submitted On 20-JUL-2004
cowwoc
mittendo ,

   If the issue is still open in JDK 1.4.1, please file a bug report against it and ask for this issue to be reopened.



PLEASE NOTE: JDK6 is formerly known as Project Mustang