You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Dan Armbrust <da...@gmail.com> on 2011/08/18 20:03:42 UTC

How to handle the AWT-Windows thread?

So, yesterday, I finally start working on upgrading on old application
set to a current 6 release of Tomcat.

(Sigh, behind the truck already, seeing the announcement of the next
version today bad timing by me...  beside the point)

Some of my web applications are using JFreeChart to generate images.
Even though I'm using the -Djava.awt.headless=true flag, Tomcat is
still telling this upon shutdown:

SEVERE: The web application [/ap] appears to have started a thread
named [AWT-Windows] but has failed to stop it. This is very likely to
create a memory leak.

How does one handle this properly?  It isn't a critical issue for me,
since we never undeploy / redeploy anyway, without restarting the
entire server.

But now it is just annoying me.  Someone must have had to deal with
this before?  I can't figure out how I can either prevent the JVM from
creating this thread, or how to get the JVM to let the thread end.

I haven't dug for it yet, but I assume there is a switch I can use to
shut off the memory detect warnings?  (If I can't figure out how to
fix all my issues)  I can't ship code to the customers that logs
"SEVERE" errors on shutdown.

Thanks,

Dan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: [OT] Re: How to handle the AWT-Windows thread?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Pid,

On 8/21/2011 4:53 AM, Pid wrote:
> On 21/08/2011 01:19, Christopher Schultz wrote:
>> I'm not sure how one would intercept the call, though. I've
>> never looked into it, but I would guess that
>> Toolkit.getDefaultToolkit can be configured to return an object
>> of a different class -- one that would presumably temporarily set
>> the CCL to the system ClassLoader.
> 
> Hmm.  Modifying the loadClass(str) method might suffice, on the
> basis that a call to load Toolkit.class is likely to result in a 
> Toolkit.getDefaultToolkit() - rather than trying to intercept the
> method call.

Meh.  Explicit configuration beats guessing IMHO.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5UHG8ACgkQ9CaO5/Lv0PBPXwCglxYZHLmcnQb4eRyvwmFZ4H4l
kSYAn184s7Mmm1Jr9yrj7FSRmdAfPUbi
=mXUj
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: [OT] Re: How to handle the AWT-Windows thread?

Posted by Pid <pi...@pidster.com>.
On 21/08/2011 01:19, Christopher Schultz wrote:
> Pid,
> 
> On 8/20/2011 6:06 PM, Pid wrote:
>> On 19/08/2011 15:45, Christopher Schultz wrote:
>>> Dan,
>>>
>>> On 8/18/2011 5:22 PM, Dan Armbrust wrote:
>>>> Toolkit.getDefaultToolkit().createImage(new byte[]{});
>>>
>>> Simply calling getDefaultToolkit will do the trick: you don't
>>> have to waste time creating an image.
>>>
>>> I'll implement this in the JreLeakPreventionListener, but it will
>>> be /disabled/ by default because it creates an extra thread.
> 
> 
>> For this type of problem would it be useful to intercept the call
>> to load the class & then trigger the protection 'on demand'?
> 
> I'm not sure how one would intercept the call, though. I've never
> looked into it, but I would guess that Toolkit.getDefaultToolkit can
> be configured to return an object of a different class -- one that
> would presumably temporarily set the CCL to the system ClassLoader.

Hmm.  Modifying the loadClass(str) method might suffice, on the basis
that a call to load Toolkit.class is likely to result in a
Toolkit.getDefaultToolkit() - rather than trying to intercept the method
call.


p

>> It might be a bit of a stretch to make it happen safely,
>> admittedly.
> 
> +1
> 
> -chris
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 



Re: [OT] Re: How to handle the AWT-Windows thread?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Pid,

On 8/20/2011 6:06 PM, Pid wrote:
> On 19/08/2011 15:45, Christopher Schultz wrote:
>> Dan,
>> 
>> On 8/18/2011 5:22 PM, Dan Armbrust wrote:
>>> Toolkit.getDefaultToolkit().createImage(new byte[]{});
>> 
>> Simply calling getDefaultToolkit will do the trick: you don't
>> have to waste time creating an image.
>> 
>> I'll implement this in the JreLeakPreventionListener, but it will
>> be /disabled/ by default because it creates an extra thread.
> 
> 
> For this type of problem would it be useful to intercept the call
> to load the class & then trigger the protection 'on demand'?

I'm not sure how one would intercept the call, though. I've never
looked into it, but I would guess that Toolkit.getDefaultToolkit can
be configured to return an object of a different class -- one that
would presumably temporarily set the CCL to the system ClassLoader.

> It might be a bit of a stretch to make it happen safely,
> admittedly.

+1

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5QTxEACgkQ9CaO5/Lv0PCNDwCeIwTKF9JKampBWCuns642qw2T
VOkAn0bFLTeLlSEurbj7mK9NHVeG1F3u
=xK1L
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


[OT] Re: How to handle the AWT-Windows thread?

Posted by Pid <pi...@pidster.com>.
On 19/08/2011 15:45, Christopher Schultz wrote:
> Dan,
> 
> On 8/18/2011 5:22 PM, Dan Armbrust wrote:
>> Toolkit.getDefaultToolkit().createImage(new byte[]{});
> 
> Simply calling getDefaultToolkit will do the trick: you don't have to
> waste time creating an image.
> 
> I'll implement this in the JreLeakPreventionListener, but it will be
> /disabled/ by default because it creates an extra thread.


For this type of problem would it be useful to intercept the call to
load the class & then trigger the protection 'on demand'?

It might be a bit of a stretch to make it happen safely, admittedly.


p


Re: How to handle the AWT-Windows thread?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Dan,

On 8/18/2011 5:22 PM, Dan Armbrust wrote:
> Toolkit.getDefaultToolkit().createImage(new byte[]{});

Simply calling getDefaultToolkit will do the trick: you don't have to
waste time creating an image.

I'll implement this in the JreLeakPreventionListener, but it will be
/disabled/ by default because it creates an extra thread.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5Odv0ACgkQ9CaO5/Lv0PCcgQCgmJSbaZfi44FrJNsZRrKzUjO7
P8sAni966fu3A/UyixaIysxI8UNBXtXS
=XUTK
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to handle the AWT-Windows thread?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Pid,

On 8/18/2011 6:05 PM, Pid wrote:
> On 18/08/2011 22:22, Dan Armbrust wrote:
>> Toolkit.getDefaultToolkit().createImage(new byte[]{});
>> 
>> which avoids "Headless" issues, but still kicks off the
>> AWT-Windows thread.
>> 
>> And since it is no longer tied to the context class loader,
>> Tomcat doesn't detect any issues on shutdown.
> 
> Doesn't the leak prevention listener do this?

No, JLPL protects against pinning of the CCL when using
sun.awt.AppContext.getAppContext().

I think this might be a decent option to implement, disabled by
default (because nobody wants an extra thread around for no reason).

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5Oc5kACgkQ9CaO5/Lv0PCW0ACfWxDDEmkYIgW29ZHYYqVsnWAF
yFcAoJSK44YKlovB8xoYbCX9o1kNow5R
=FYWg
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to handle the AWT-Windows thread?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Dan and Pid,

On 8/18/2011 6:05 PM, Pid wrote:
> On 18/08/2011 22:22, Dan Armbrust wrote:
>> Toolkit.getDefaultToolkit().createImage(new byte[]{});
>> 
>> which avoids "Headless" issues, but still kicks off the
>> AWT-Windows thread.
> 
> Doesn't the leak prevention listener do this?

Fixed in 7.0.x trunk, proposed for 6.0.x. Not suer how 8.0.x is
working right now...

https://issues.apache.org/bugzilla/show_bug.cgi?id=51688

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5OjzkACgkQ9CaO5/Lv0PB+MQCfQFyz728h4lKFA7/zf6WXz/+H
kGAAn1khstTA+WYDeWCVNT/FJ6UPwnS5
=NLRF
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to handle the AWT-Windows thread?

Posted by Pid <pi...@pidster.com>.
On 18/08/2011 22:22, Dan Armbrust wrote:
> On Thu, Aug 18, 2011 at 2:13 PM, Christopher Schultz
> <ch...@christopherschultz.net> wrote:
> 
>> The JVM should not launch more than one AWT thread, so you should be
>> okay. The only issue would be whether or not it inherits the webapp's
>> context ClassLoader which would really represent a memory leak if you
>> do live webapp reloads (or undeploy/redeploy).
>>
>> You would only get this message if the WebappClassLoader was being
>> used as the ContextClassLoader for this thread, so that must be the case.
>>
>> You should be able to trick the AWT thread to start using the system
>> class loader in a ServletContextListener that looks something like this:
>>
>> init() {
>>
>>  Thread myThread = Thread.currentThread();
>>  ClassLoader ccl = myThread.getContextClassLoader(); // PUSH
>>  myThread.setContextClassLoader(ClassLoader.getSystemClassLoader());
>>
>>  // do something that triggers the creation of the AWT -- maybe
>>  // something like "new java.awt.Frame()"
>>
>>  myThread.setContextClassLoader(ccl); // POP
>> }
>>
>> This will pin the system ClassLoader into memory (big deal) instead of
>> your webapp's. This should fix this particular leak and, by extension,
>> remove the error message from your logs.
>>
>> - -chris
> 
> You sir, are a clever clever man :)
> 
> Works perfectly.  The AWT thing that I did was simply
> 
> Toolkit.getDefaultToolkit().createImage(new byte[]{});
> 
> which avoids "Headless" issues, but still kicks off the AWT-Windows thread.
> 
> And since it is no longer tied to the context class loader, Tomcat
> doesn't detect any issues on shutdown.

Doesn't the leak prevention listener do this?


p




Re: How to handle the AWT-Windows thread?

Posted by Dan Armbrust <da...@gmail.com>.
On Thu, Aug 18, 2011 at 2:13 PM, Christopher Schultz
<ch...@christopherschultz.net> wrote:

> The JVM should not launch more than one AWT thread, so you should be
> okay. The only issue would be whether or not it inherits the webapp's
> context ClassLoader which would really represent a memory leak if you
> do live webapp reloads (or undeploy/redeploy).
>
> You would only get this message if the WebappClassLoader was being
> used as the ContextClassLoader for this thread, so that must be the case.
>
> You should be able to trick the AWT thread to start using the system
> class loader in a ServletContextListener that looks something like this:
>
> init() {
>
>  Thread myThread = Thread.currentThread();
>  ClassLoader ccl = myThread.getContextClassLoader(); // PUSH
>  myThread.setContextClassLoader(ClassLoader.getSystemClassLoader());
>
>  // do something that triggers the creation of the AWT -- maybe
>  // something like "new java.awt.Frame()"
>
>  myThread.setContextClassLoader(ccl); // POP
> }
>
> This will pin the system ClassLoader into memory (big deal) instead of
> your webapp's. This should fix this particular leak and, by extension,
> remove the error message from your logs.
>
> - -chris

You sir, are a clever clever man :)

Works perfectly.  The AWT thing that I did was simply

Toolkit.getDefaultToolkit().createImage(new byte[]{});

which avoids "Headless" issues, but still kicks off the AWT-Windows thread.

And since it is no longer tied to the context class loader, Tomcat
doesn't detect any issues on shutdown.

Thanks,

Dan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to handle the AWT-Windows thread?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Dan,

On 8/18/2011 2:38 PM, Dan Armbrust wrote:
> On the plus side, since they never actually remove anything they 
> deprecate... maybe I can just "stop" the thread.  Hmm.

The JVM should not launch more than one AWT thread, so you should be
okay. The only issue would be whether or not it inherits the webapp's
context ClassLoader which would really represent a memory leak if you
do live webapp reloads (or undeploy/redeploy).

You would only get this message if the WebappClassLoader was being
used as the ContextClassLoader for this thread, so that must be the case.

You should be able to trick the AWT thread to start using the system
class loader in a ServletContextListener that looks something like this:

init() {

  Thread myThread = Thread.currentThread();
  ClassLoader ccl = myThread.getContextClassLoader(); // PUSH
  myThread.setContextClassLoader(ClassLoader.getSystemClassLoader());

  // do something that triggers the creation of the AWT -- maybe
  // something like "new java.awt.Frame()"

  myThread.setContextClassLoader(ccl); // POP
}

This will pin the system ClassLoader into memory (big deal) instead of
your webapp's. This should fix this particular leak and, by extension,
remove the error message from your logs.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5NZGkACgkQ9CaO5/Lv0PB6bgCgptx6nHRmbobmlscvujuzaNrL
XAoAnRedjsOD0bPuF9Rv/N1c+4g4w+4p
=rJYz
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to handle the AWT-Windows thread?

Posted by Dan Armbrust <da...@gmail.com>.
>> (If I can't figure out how to
>> fix all my issues)  I can't ship code to the customers that logs
>> "SEVERE" errors on shutdown.
>
> All the leaks should be fixable / possible to workaround.
>
> Mark

If I could update all of my dependencies... I'm guessing many would
just go away.  Unfortunately, I'm stuck with a rather broken release
of apache axis for now... and all of the broken libraries it depended
on.  At some point, I'm going to get tired of trying to find old
source, and writing reflection hacks to clean up after their bugs...

Legacy support is fun :)

Thanks for the tips.  I'm surprised that more people don't encounter
the AWT issue.  Sigh.  Guess it goes back to Sun never really getting
that design right... and then never fixing it.

On the plus side, since they never actually remove anything they
deprecate... maybe I can just "stop" the thread.  Hmm.

Dan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to handle the AWT-Windows thread?

Posted by Mark Thomas <ma...@apache.org>.
On 18/08/2011 19:03, Dan Armbrust wrote:
> So, yesterday, I finally start working on upgrading on old application
> set to a current 6 release of Tomcat.
> 
> (Sigh, behind the truck already, seeing the announcement of the next
> version today bad timing by me...  beside the point)
> 
> Some of my web applications are using JFreeChart to generate images.
> Even though I'm using the -Djava.awt.headless=true flag, Tomcat is
> still telling this upon shutdown:
> 
> SEVERE: The web application [/ap] appears to have started a thread
> named [AWT-Windows] but has failed to stop it. This is very likely to
> create a memory leak.
> 
> How does one handle this properly?  It isn't a critical issue for me,
> since we never undeploy / redeploy anyway, without restarting the
> entire server.
> 
> But now it is just annoying me.  Someone must have had to deal with
> this before?  I can't figure out how I can either prevent the JVM from
> creating this thread, or how to get the JVM to let the thread end.

I suspect neither of those is an option. However, what you can probably
do (once you figure out which call is triggering the creation of this
thread) is something along the lines of this:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java?view=markup

> I haven't dug for it yet, but I assume there is a switch I can use to
> shut off the memory detect warnings?

You can disable log messages for that class (not something I'd
recommend) but you can't disable the memory leak checks. There is an
outstanding enhancement request to skip the warnings in situations where
they (arguably) can be safely ignored -
https://issues.apache.org/bugzilla/show_bug.cgi?id=50175 - although the
embedded vs. standalone point is a valid one that will need some careful
thought to ensure the right solution is implemented.

> (If I can't figure out how to
> fix all my issues)  I can't ship code to the customers that logs
> "SEVERE" errors on shutdown.

All the leaks should be fixable / possible to workaround.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org