You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by jean-frederic clere <jf...@gmail.com> on 2009/12/21 11:12:12 UTC

release 6.0.21

Hi,

Later today I will tag and go for the release, make sure all the patches 
you want to see in are committed :-)

It will also add binaries for tc-native

Comments?

Cheers

Jean-Frederic

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


Re: release 6.0.21

Posted by Mark Thomas <ma...@apache.org>.
On 21/12/2009 10:12, jean-frederic clere wrote:
> Hi,
> 
> Later today I will tag and go for the release, make sure all the patches
> you want to see in are committed :-)

I've finished proposing everything I'd like to see in 6.0.21. I'll try
and commit anything that gets enough votes before the tag.

Cheers,

Mark



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


Re: release 6.0.21

Posted by Mark Thomas <ma...@apache.org>.
On 22/12/2009 07:32, Rainer Frey (Inxmail GmbH) wrote:
> On Monday 21 December 2009 18:13:51 Mark Thomas wrote:
>> Konstantin's comments about the JDBC-ODBC bridge got me looking at this
>> more closely. There was a bug in the de-registration code that mean it
>> was a little over-zealous on its clean up. Patch to trunk and proposal
>> for 6.0.21 to follow shortly. With the patch in place, your original
>> code should work happily.
> 
> You're confusing me now :-)
> Do you mean my ServletContextListener from two mails before, or the really 
> original test case without any Listener at all?

The original test case without a listener should be fine.

> If the former, does that mean the container level listener is necessary, or 
> that it won't  work at all? And what does "container level" mean w/ regard to 
> where to attach the  listener? Server, Engine, Host  or does this not matter 
> at all?

No listener required.

Mark



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


Re: release 6.0.21

Posted by "Rainer Frey (Inxmail GmbH)" <ra...@inxmail.de>.
On Monday 21 December 2009 18:13:51 Mark Thomas wrote:
> On 21/12/2009 15:59, Mark Thomas wrote:
> > For an example of a container level lifecycle listener take a look at
> > this commit. That should give you the idea.
> >
> > http://svn.apache.org/viewvc?view=revision&revision=828196
>
> This might be complete nonsense :)

Oh ;-)

> Konstantin's comments about the JDBC-ODBC bridge got me looking at this
> more closely. There was a bug in the de-registration code that mean it
> was a little over-zealous on its clean up. Patch to trunk and proposal
> for 6.0.21 to follow shortly. With the patch in place, your original
> code should work happily.

You're confusing me now :-)
Do you mean my ServletContextListener from two mails before, or the really 
original test case without any Listener at all?

If the former, does that mean the container level listener is necessary, or 
that it won't  work at all? And what does "container level" mean w/ regard to 
where to attach the  listener? Server, Engine, Host  or does this not matter 
at all?

> Mark

Rainer

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


Re: release 6.0.21

Posted by Mark Thomas <ma...@apache.org>.
On 21/12/2009 15:59, Mark Thomas wrote:
> On 21/12/2009 15:13, Rainer Frey (Inxmail GmbH) wrote:
>> On Monday 21 December 2009 15:23:42 Mark Thomas wrote:
>>> The memory leak is caused by the DriverManager implementation. It holds
>>> a reference to the Driver. If the Driver was loaded by the web
>>> application then the Driver holds a reference to the WebappClassLoader.
>>> This in turn holds references to every class it has ever loaded. This
>>> can result in a significant PermGen leak on application reload.
>>>
>>> All the methods I have looked at do auto-registration but never
>>> de-registration. Given how DriverManager works that is a guaranteed
>>> memory leak on reload. In certain circumstances you can rely on
>>> auto-registration but it is safe to register and deregister yourself.
>>
>> Thanks for the explanation, I understand now.
>>
>>>>> If you get a chance before I get to it later today, try using a context
>>>>> listener to register and de-register the driver when your app starts and
>>>>> stops and let us know how you get on.
>>>>
>>>> I implemented the ServletContextListener below, and I don't get any
>>>> exceptions anymore.
>>>
>>> That is exactly the sort of thing I had in mind.
>>
>> Our product is a tomcat server with several (up to 25-40) copies of the same 
>> webapp (one for each customer).  When this  listener in one application would 
>> kick in, no other would be influenced, right?
> 
> In your scenario, if the web app behaves the same way as the test case
> attached to the bug, you are likely to have issues. I think you'd need
> to use the container level lifecycle listener approach.
> 
>> Actually each of those webapps can use one of 4 supported databases, but in 
>> most installations only one driver jar is actually available. Would you 
>> recommend this approach in this scenario rather than the context listener, or 
>> is there a drawback?
> 
> See above.
> 
> For an example of a container level lifecycle listener take a look at
> this commit. That should give you the idea.
> 
> http://svn.apache.org/viewvc?view=revision&revision=828196

This might be complete nonsense :)

Konstantin's comments about the JDBC-ODBC bridge got me looking at this
more closely. There was a bug in the de-registration code that mean it
was a little over-zealous on its clean up. Patch to trunk and proposal
for 6.0.21 to follow shortly. With the patch in place, your original
code should work happily.

Mark



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


Re: release 6.0.21

Posted by Mark Thomas <ma...@apache.org>.
On 21/12/2009 15:13, Rainer Frey (Inxmail GmbH) wrote:
> On Monday 21 December 2009 15:23:42 Mark Thomas wrote:
>> The memory leak is caused by the DriverManager implementation. It holds
>> a reference to the Driver. If the Driver was loaded by the web
>> application then the Driver holds a reference to the WebappClassLoader.
>> This in turn holds references to every class it has ever loaded. This
>> can result in a significant PermGen leak on application reload.
>>
>> All the methods I have looked at do auto-registration but never
>> de-registration. Given how DriverManager works that is a guaranteed
>> memory leak on reload. In certain circumstances you can rely on
>> auto-registration but it is safe to register and deregister yourself.
> 
> Thanks for the explanation, I understand now.
> 
>>>> If you get a chance before I get to it later today, try using a context
>>>> listener to register and de-register the driver when your app starts and
>>>> stops and let us know how you get on.
>>>
>>> I implemented the ServletContextListener below, and I don't get any
>>> exceptions anymore.
>>
>> That is exactly the sort of thing I had in mind.
> 
> Our product is a tomcat server with several (up to 25-40) copies of the same 
> webapp (one for each customer).  When this  listener in one application would 
> kick in, no other would be influenced, right?

In your scenario, if the web app behaves the same way as the test case
attached to the bug, you are likely to have issues. I think you'd need
to use the container level lifecycle listener approach.

> Actually each of those webapps can use one of 4 supported databases, but in 
> most installations only one driver jar is actually available. Would you 
> recommend this approach in this scenario rather than the context listener, or 
> is there a drawback?

See above.

For an example of a container level lifecycle listener take a look at
this commit. That should give you the idea.

http://svn.apache.org/viewvc?view=revision&revision=828196

Mark



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


Re: release 6.0.21

Posted by "Rainer Frey (Inxmail GmbH)" <ra...@inxmail.de>.
On Monday 21 December 2009 15:23:42 Mark Thomas wrote:
> The memory leak is caused by the DriverManager implementation. It holds
> a reference to the Driver. If the Driver was loaded by the web
> application then the Driver holds a reference to the WebappClassLoader.
> This in turn holds references to every class it has ever loaded. This
> can result in a significant PermGen leak on application reload.
>
> All the methods I have looked at do auto-registration but never
> de-registration. Given how DriverManager works that is a guaranteed
> memory leak on reload. In certain circumstances you can rely on
> auto-registration but it is safe to register and deregister yourself.

Thanks for the explanation, I understand now.

> >> If you get a chance before I get to it later today, try using a context
> >> listener to register and de-register the driver when your app starts and
> >> stops and let us know how you get on.
> >
> > I implemented the ServletContextListener below, and I don't get any
> > exceptions anymore.
>
> That is exactly the sort of thing I had in mind.

Our product is a tomcat server with several (up to 25-40) copies of the same 
webapp (one for each customer).  When this  listener in one application would 
kick in, no other would be influenced, right?

> > But I'm not sure about this thing. Are drivers required by spec to
> > provide a public parameterless constructor, and is it safe to create and
> > manage instances of a Driver on my own?
>
> Most do, but it doesn't appear to be required. In your circumstances,
> you could use a LifecycleListener defined at the container level that
> just called Class.forName(String). In that scenario the common class
> loader would load the driver (as now) but it would also be the context
> class loader so DriverManager would pin the common class loader in
> memory which is not an issue (since it is never reloaded). In this case
> the memory leak protection code wouldn't kick in on webapp reload and
> all would be fine in your app.

Actually each of those webapps can use one of 4 supported databases, but in 
most installations only one driver jar is actually available. Would you 
recommend this approach in this scenario rather than the context listener, or 
is there a drawback?

Thanks for all your feedback on this, Mark. This is a great service to us!

> Mark

Rainer

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


Re: release 6.0.21

Posted by "Rainer Frey (Inxmail GmbH)" <ra...@inxmail.de>.
On Monday 21 December 2009 15:23:42 Mark Thomas wrote:
> Most do, but it doesn't appear to be required. In your circumstances,
> you could use a LifecycleListener defined at the container level that
> just called Class.forName(String). 

Hi Mark,

what do you mean with "container level" here?

Rainer

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


Re: release 6.0.21

Posted by Mark Thomas <ma...@apache.org>.
On 21/12/2009 14:11, Rainer Frey (Inxmail GmbH) wrote:
> On Monday 21 December 2009 12:04:59 Mark Thomas wrote:
>> My guess is that you are relying on the auto-driver registration
>> process. It is this process that triggers the memory leak so Tomcat now
>> forcibly de-registers any drivers the JVM auto-registers.
> 
> I do, mostly on the presence of a static initializer block in the driver 
> class, as most drivers that we use do not yet implement JDBC4 fully.
> What exactly is the memory leak? Is relying on the auto-registration 
> discouraged altogether, or is the service definition method of JDBC 4 safe?

The memory leak is caused by the DriverManager implementation. It holds
a reference to the Driver. If the Driver was loaded by the web
application then the Driver holds a reference to the WebappClassLoader.
This in turn holds references to every class it has ever loaded. This
can result in a significant PermGen leak on application reload.

All the methods I have looked at do auto-registration but never
de-registration. Given how DriverManager works that is a guaranteed
memory leak on reload. In certain circumstances you can rely on
auto-registration but it is safe to register and deregister yourself.

>> If you get a chance before I get to it later today, try using a context
>> listener to register and de-register the driver when your app starts and
>> stops and let us know how you get on.
> 
> I implemented the ServletContextListener below, and I don't get any exceptions 
> anymore.

That is exactly the sort of thing I had in mind.

> But I'm not sure about this thing. Are drivers required by spec to 
> provide a public parameterless constructor, and is it safe to create and 
> manage instances of a Driver on my own?

Most do, but it doesn't appear to be required. In your circumstances,
you could use a LifecycleListener defined at the container level that
just called Class.forName(String). In that scenario the common class
loader would load the driver (as now) but it would also be the context
class loader so DriverManager would pin the common class loader in
memory which is not an issue (since it is never reloaded). In this case
the memory leak protection code wouldn't kick in on webapp reload and
all would be fine in your app.

> Or do I need a separate instantiation 
> mechanism for each supported driver? I always regarded  these things as 
> internal to the driver implementation. Maybe you were thinking of a different 
> approach to deregister and register a driver that I just don't see?

I am afraid not. DriverManager and container environments can play
together nicely but you do need to be very careful. Unfortunately, this
is an issue that web app developers are not that familiar with.

Mark



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


Re: release 6.0.21

Posted by "Rainer Frey (Inxmail GmbH)" <ra...@inxmail.de>.
On Monday 21 December 2009 12:04:59 Mark Thomas wrote:
> On 21/12/2009 10:53, Rainer Frey wrote:
[...]
> > but I hoped that someone would take a
> > look at issue https://issues.apache.org/bugzilla/show_bug.cgi?id=48214
> > before a release is made 
>
> I hadn't forgotten that one - I just hadn't got around to looking at it.
> I have a few ideas about what might be going on.

I assumed so, but I was afraid there wouldn't be time before the release.

> My guess is that you are relying on the auto-driver registration
> process. It is this process that triggers the memory leak so Tomcat now
> forcibly de-registers any drivers the JVM auto-registers.

I do, mostly on the presence of a static initializer block in the driver 
class, as most drivers that we use do not yet implement JDBC4 fully.
What exactly is the memory leak? Is relying on the auto-registration 
discouraged altogether, or is the service definition method of JDBC 4 safe?

> If you get a chance before I get to it later today, try using a context
> listener to register and de-register the driver when your app starts and
> stops and let us know how you get on.

I implemented the ServletContextListener below, and I don't get any exceptions 
anymore. But I'm not sure about this thing. Are drivers required by spec to 
provide a public parameterless constructor, and is it safe to create and 
manage instances of a Driver on my own? Or do I need a separate instantiation 
mechanism for each supported driver? I always regarded  these things as 
internal to the driver implementation. Maybe you were thinking of a different 
approach to deregister and register a driver that I just don't see?

Here's the code (minus exception handling and logging):
public class JdbcDriverRegistrationListener implements ServletContextListener
{
  private Driver driver;

  public void contextInitialized( ServletContextEvent evt )
  {
    ServletContext context = evt.getServletContext();
    String driverName = context.getInitParameter( "jdbc.driver" );
    try
    {
      Class<Driver> driverClass = (Class<Driver>)Class.forName( driverName );
      this.driver = driverClass.newInstance();
      DriverManager.registerDriver( this.driver );
    }
    catch( Exception x )
    {}		
 }

  public void contextDestroyed( ServletContextEvent evt )
  {
     DriverManager.deregisterDriver( this.driver );
  }
}

> Cheers,
>
> Mark

Rainer

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


Re: release 6.0.21

Posted by Mark Thomas <ma...@apache.org>.
On 21/12/2009 10:53, Rainer Frey wrote:
> On Monday 21 December 2009 11:12:12 jean-frederic clere wrote:
>> Hi,
>>
>> Later today I will tag and go for the release, make sure all the patches
>> you want to see in are committed :-)
> 
> Well, I'm no committer and I don't understand the relevant code well  enough 
> to possibly create a patch, but I hoped that someone would take a look at 
> issue https://issues.apache.org/bugzilla/show_bug.cgi?id=48214 before a 
> release is made (This issue was introduced by changes after 6.0.20, and Mark 
> Thomas told me on the users list to create a bugzilla entry for that).

I hadn't forgotten that one - I just hadn't got around to looking at it.
I have a few ideas about what might be going on.

My guess is that you are relying on the auto-driver registration
process. It is this process that triggers the memory leak so Tomcat now
forcibly de-registers any drivers the JVM auto-registers.

If you get a chance before I get to it later today, try using a context
listener to register and de-register the driver when your app starts and
stops and let us know how you get on.

Cheers,

Mark



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


Re: release 6.0.21

Posted by Rainer Frey <ra...@inxmail.de>.
On Monday 21 December 2009 11:12:12 jean-frederic clere wrote:
> Hi,
>
> Later today I will tag and go for the release, make sure all the patches
> you want to see in are committed :-)

Well, I'm no committer and I don't understand the relevant code well  enough 
to possibly create a patch, but I hoped that someone would take a look at 
issue https://issues.apache.org/bugzilla/show_bug.cgi?id=48214 before a 
release is made (This issue was introduced by changes after 6.0.20, and Mark 
Thomas told me on the users list to create a bugzilla entry for that).

Regards
Rainer



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