You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Simon Kitching <sk...@apache.org> on 2006/08/21 11:27:07 UTC
Re: [beanutils] [logging] Webapp using commons-logging fails to
start in Tomcat 4.1.x when beanutils 1.7.0 is used by Tomcat
Hi Mark,
Firstly, the 1.1.0 release of commons-logging will hopefully not have
this problem; you don't indicate what version of commons-logging is
present when this problem occurs. Could you try upgrading the JCL
implementation in the tomcat path to the latest version and see what
happens?
Regarding static log instances, this is really a bad idea for a number
of reasons, and this is NOT specific to commons-logging but common to
any logging library that allows per-webapp logging configuration. This
includes log4j, slf4j and JULI. See:
http://wiki.apache.org/jakarta-commons/Logging/StaticLog
If beanutils is using static loggers then that really should be fixed.
Actually, beanutil's liberal use of static members and methods has
always struck me as being incredibly dangerous. I certainly don't want a
datatype converter registered by one webapp to be visible in another! I
would therefore suggest that tomcat (and all other apps) completely
avoid using any static beanutils methods, and instead always access
specific *instances* of the beanutils classes for beanutils
functionality; that might avoid the logging issue completely. Or dump
BeanUtils; there is some useful stuff in there but a lot of pretty scary
stuff too..
I can't see why beanutils 1.6.1 would be "better" than 1.7.0. Your
statement that because BeanUtils/ConvertUtils were static, the objects
were created by the Tomcat classloader doesn't seem right to me. If the
jar is bundled in a webapp, and the webapp has child-first classloading
then the webapp's classloader will load those classes and hold its own
copy of those statics, no? A singleton object having the same object
types held as members instead of statics should have exactly the same
behaviour as far as I can see, because the singleton reference is a
static. There is one exception: the members will be initialised when the
first singleton instance is created, not at class load time. Maybe it is
that delayed member initialisation that is responsible for any behaviour
difference you see?
The blog entry referenced is interesting, but I can't for the moment see
why it would have any effect at all. If child-first lookup is in action,
and the class is available to the child classloader then that should
take precedence over the parent classloader's version. And if
parent-first lookup is in action, then the code shown is the default
behaviour anyway isn't it? I must be missing something..will think about
it some more.
Mark, what specifically is your issue here? Are you a tomcat developer,
or trying to write webapps to run on tomcat, or something else?
Regards,
Simon
On Sun, 2006-08-20 at 19:36 -0400, Mark Thomas wrote:
> Hi,
>
> The most recent Tomcat 4 release upgraded from beanutils 1.6.1 to
> 1.7.0 and this introduced a conflict with commons-logging (see
> http://issues.apache.org/bugzilla/show_bug.cgi?id=40252). As the
> issues boils down to fun and games with containers and classloader
> hierarchies, this might not be a beanutils issue at all but given the
> issue became apparent after a change in beanutils this seems like the
> right place to start.
>
> Since this discussion revolves around changes in the beanutils code, I
> am posting this to the dev list. If it is felt the users list is more
> appropriate, I am happy to move this thread to that list instead.
>
> With beanutils 1.6.1 utility classes such as BeanUtils and
> ConvertUtils were static and hence the associated Log instances were
> also static. All these objects were created by the Tomcat common
> classloader and all was well.
>
> In beanutils 1.7.0 the BeanUtilsBean class was introduced as
> per-context-classloader pseudo singletons. Providing commons-logging
> is not present in the webapp classloader then all is well. As soon as
> commons-logging is present in the webapp classloader, when the per
> context classloader instance of ConvertUtilsBean creates a logger it
> uses the Log class from the webapp classloader which conflicts with
> that in the common classloader and "Invalid class loader hierarchy.
> You have more than one version of 'org.apache.commons.logging.Log'
> visible, which is not allowed." results.
>
> The only option for the webapp developer is not to include
> commons-logging but this does make for portable webapps - not all
> containers use commons-logging internally and a webapp may require
> this library. For now, my short-term solution is to revert to
> beanutils 1.6.1 for a TC4.1.33 release.
>
> Longer term, I wonder if the same sort of trick the OP for the above
> bug uses in webapps (see
> http://rbodkin.blogs.com/ron_bodkins_blog/2006/07/stupid_log_tric.html)
> could be used in beanutils. I would be happy to work on a patch in
> this direction if it was thought to be useful. However, I would value
> the insight of those more familiar with the beanutils code before
> starting since I don't want to waste time on a pointless exercise.
>
> Regards,
>
> Mark
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: [beanutils] [logging] Webapp using commons-logging fails to start
in Tomcat 4.1.x when beanutils 1.7.0 is used by Tomcat
Posted by Mark Thomas <ma...@apache.org>.
Simon Kitching wrote:
> Firstly, the 1.1.0 release of commons-logging will hopefully not have
> this problem; you don't indicate what version of commons-logging is
> present when this problem occurs. Could you try upgrading the JCL
> implementation in the tomcat path to the latest version and see what
> happens?
Tomcat currently uses commons-logging 1.0.4 but sees the same issue
with 1.1.0.
> If beanutils is using static loggers then that really should be fixed.
It has been fixed in 1.7.0 but this causes issues for Tomcat.
> Actually, beanutil's liberal use of static members and methods has
> always struck me as being incredibly dangerous. I certainly don't want a
> datatype converter registered by one webapp to be visible in another! I
> would therefore suggest that tomcat (and all other apps) completely
> avoid using any static beanutils methods, and instead always access
> specific *instances* of the beanutils classes for beanutils
> functionality; that might avoid the logging issue completely. Or dump
> BeanUtils; there is some useful stuff in there but a lot of pretty scary
> stuff too..
Beanutils is only used directly in a few places but where we are
seeing problems is when we use commons-digester of which beanutils is
a dependency.
> I can't see why beanutils 1.6.1 would be "better" than 1.7.0.
Generally, I am sure it isn't. However, in this particular situation
1.6.1 works and 1.7.0 does not.
> Your
> statement that because BeanUtils/ConvertUtils were static, the objects
> were created by the Tomcat classloader doesn't seem right to me.
Tomcat uses digester internally. First to configure itself (objects
loaded with common classloader) and then to configure webapps (objects
loaded with webapp classloader). Since in the static case the logs are
created once when the static is created then all objects are created
in the common classloader and there are no complaints from
commons-logging.
> If the
> jar is bundled in a webapp, and the webapp has child-first classloading
> then the webapp's classloader will load those classes and hold its own
> copy of those statics, no?
Agreed. The problem occurs when commons-logging is present in the
webapp loader and in the common-loader.
> A singleton object having the same object
> types held as members instead of statics should have exactly the same
> behaviour as far as I can see, because the singleton reference is a
> static.
These are pseudo singletons (commons-beanutils terminology). They are
not statics but one per classloader instances.
> There is one exception: the members will be initialised when the
> first singleton instance is created, not at class load time. Maybe it is
> that delayed member initialisation that is responsible for any behaviour
> difference you see?
Indeed. When commons-digester is configuring the webapp, it creates a
ConvertUtilsBean for that classloader which in turn creates a log
instance. If commons-logging is present in the webapp classloader and
the common classloader it all goes horribly wrong.
> The blog entry referenced is interesting, but I can't for the moment see
> why it would have any effect at all. If child-first lookup is in action,
> and the class is available to the child classloader then that should
> take precedence over the parent classloader's version. And if
> parent-first lookup is in action, then the code shown is the default
> behaviour anyway isn't it? I must be missing something..will think about
> it some more.
It gets around the commons-logging requirement that only one instance
of commons-logging can exist in the classloader hierarchy. If the
container provides it, the webapp uses it it. If it doesn't, the
webapp uses its own. It essentially forces parent first classloading
for commons-logging. Where a webapp requires commons-logging, it
enables the webapp to be shipped without the users having to be
concerned about the one commons-logging instance per classloader
hierarchy issue.
> Mark, what specifically is your issue here? Are you a tomcat developer,
> or trying to write webapps to run on tomcat, or something else?
Tomcat developer, trying to find a better fix to this bug than
reverting to commons-beanutils 1.6.1
Mark
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: [beanutils] [logging] Webapp using commons-logging fails to start
in Tomcat 4.1.x when beanutils 1.7.0 is used by Tomcat
Posted by Mark Thomas <ma...@apache.org>.
Mark Thomas wrote:
>> You say you've tried commons-logging 1.1.0. Can you please confirm for
>> me that you replaced the commons-logging.jar file in $TOMCAT_HOME/lib
>> with the commons-logging-api.jar from the binary download of
>> commons-logging 1.1? You might want to try setting the following
>> environment variable:
>> -Dorg.apache.commons.logging.diagnostics.dest=/some/log/file.txt
>> then trigger the problem exception. The diagnostics feature was added to
>> JCL 1.1 to investigate just this sort of problem.
> I can't swear to trying this exact combination and I haven't done the
> diagnostic. I'll do this tonight (off to work now) and post the results.
With
- commons-logging-api-1.1.jar in common/lib
- commons-logging-1.1.jar in server/lib
- commons-logging-1.1.jar in webapp/WEB-INF/lib
there is no exception. I am guessing an old version of 1.0.4 was
around when I did my last test. Thanks for your help.
Mark
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: [beanutils] [logging] Webapp using commons-logging fails to start
in Tomcat 4.1.x when beanutils 1.7.0 is used by Tomcat
Posted by Mark Thomas <ma...@apache.org>.
Simon Kitching wrote:
> It would help if you could provide more details on exactly what
> behaviour you are seeing. In particular, are you seeing this exception
> immediately on startup of a fresh Tomcat install, or is it *any* webapp
> that triggers this, or a specific one? It will be easiest to investigate
> if there is enough info to be able to duplicate the problem.
Steps to reproduce:
- Fresh Tomcat 4.1.32 install (must be this version)
- Place commons-logging.jar in the WEB-INF/lib directory of *any* webapp
- Start Tomcat
- Console full of errors
> You say you've tried commons-logging 1.1.0. Can you please confirm for
> me that you replaced the commons-logging.jar file in $TOMCAT_HOME/lib
> with the commons-logging-api.jar from the binary download of
> commons-logging 1.1? You might want to try setting the following
> environment variable:
> -Dorg.apache.commons.logging.diagnostics.dest=/some/log/file.txt
> then trigger the problem exception. The diagnostics feature was added to
> JCL 1.1 to investigate just this sort of problem.
I can't swear to trying this exact combination and I haven't done the
diagnostic. I'll do this tonight (off to work now) and post the results.
> I unfortunately don't have a lot of spare time at the moment, but will
> try to find time to look into this once there is sufficent info to
> duplicate the problem locally.
That would be great. Much appreciated.
Mark
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: [beanutils] [logging] Webapp using commons-logging fails
to start in Tomcat 4.1.x when beanutils 1.7.0 is used by Tomcat
Posted by Simon Kitching <sk...@apache.org>.
Hi Mark,
Your report is very interesting. I do quite a bit of maintenance on
logging and digester, and a little on beanutils, so would definitely be
keen to figure out what's going on here.
It would help if you could provide more details on exactly what
behaviour you are seeing. In particular, are you seeing this exception
immediately on startup of a fresh Tomcat install, or is it *any* webapp
that triggers this, or a specific one? It will be easiest to investigate
if there is enough info to be able to duplicate the problem.
You say you've tried commons-logging 1.1.0. Can you please confirm for
me that you replaced the commons-logging.jar file in $TOMCAT_HOME/lib
with the commons-logging-api.jar from the binary download of
commons-logging 1.1? You might want to try setting the following
environment variable:
-Dorg.apache.commons.logging.diagnostics.dest=/some/log/file.txt
then trigger the problem exception. The diagnostics feature was added to
JCL 1.1 to investigate just this sort of problem.
I unfortunately don't have a lot of spare time at the moment, but will
try to find time to look into this once there is sufficent info to
duplicate the problem locally.
Regards,
Simon
On Mon, 2006-08-21 at 07:26 -0400, Mark Thomas wrote:
> Simon Kitching wrote:
> > Firstly, the 1.1.0 release of commons-logging will hopefully not have
> > this problem; you don't indicate what version of commons-logging is
> > present when this problem occurs. Could you try upgrading the JCL
> > implementation in the tomcat path to the latest version and see what
> > happens?
> Tomcat currently uses commons-logging 1.0.4 but sees the same issue
> with 1.1.0.
>
> > If beanutils is using static loggers then that really should be fixed.
> It has been fixed in 1.7.0 but this causes issues for Tomcat.
>
> > Actually, beanutil's liberal use of static members and methods has
> > always struck me as being incredibly dangerous. I certainly don't want a
> > datatype converter registered by one webapp to be visible in another! I
> > would therefore suggest that tomcat (and all other apps) completely
> > avoid using any static beanutils methods, and instead always access
> > specific *instances* of the beanutils classes for beanutils
> > functionality; that might avoid the logging issue completely. Or dump
> > BeanUtils; there is some useful stuff in there but a lot of pretty scary
> > stuff too..
> Beanutils is only used directly in a few places but where we are
> seeing problems is when we use commons-digester of which beanutils is
> a dependency.
>
> > I can't see why beanutils 1.6.1 would be "better" than 1.7.0.
> Generally, I am sure it isn't. However, in this particular situation
> 1.6.1 works and 1.7.0 does not.
>
> > Your
> > statement that because BeanUtils/ConvertUtils were static, the objects
> > were created by the Tomcat classloader doesn't seem right to me.
> Tomcat uses digester internally. First to configure itself (objects
> loaded with common classloader) and then to configure webapps (objects
> loaded with webapp classloader). Since in the static case the logs are
> created once when the static is created then all objects are created
> in the common classloader and there are no complaints from
> commons-logging.
>
> > If the
> > jar is bundled in a webapp, and the webapp has child-first classloading
> > then the webapp's classloader will load those classes and hold its own
> > copy of those statics, no?
> Agreed. The problem occurs when commons-logging is present in the
> webapp loader and in the common-loader.
>
> > A singleton object having the same object
> > types held as members instead of statics should have exactly the same
> > behaviour as far as I can see, because the singleton reference is a
> > static.
> These are pseudo singletons (commons-beanutils terminology). They are
> not statics but one per classloader instances.
>
> > There is one exception: the members will be initialised when the
> > first singleton instance is created, not at class load time. Maybe it is
> > that delayed member initialisation that is responsible for any behaviour
> > difference you see?
> Indeed. When commons-digester is configuring the webapp, it creates a
> ConvertUtilsBean for that classloader which in turn creates a log
> instance. If commons-logging is present in the webapp classloader and
> the common classloader it all goes horribly wrong.
>
> > The blog entry referenced is interesting, but I can't for the moment see
> > why it would have any effect at all. If child-first lookup is in action,
> > and the class is available to the child classloader then that should
> > take precedence over the parent classloader's version. And if
> > parent-first lookup is in action, then the code shown is the default
> > behaviour anyway isn't it? I must be missing something..will think about
> > it some more.
> It gets around the commons-logging requirement that only one instance
> of commons-logging can exist in the classloader hierarchy. If the
> container provides it, the webapp uses it it. If it doesn't, the
> webapp uses its own. It essentially forces parent first classloading
> for commons-logging. Where a webapp requires commons-logging, it
> enables the webapp to be shipped without the users having to be
> concerned about the one commons-logging instance per classloader
> hierarchy issue.
>
> > Mark, what specifically is your issue here? Are you a tomcat developer,
> > or trying to write webapps to run on tomcat, or something else?
> Tomcat developer, trying to find a better fix to this bug than
> reverting to commons-beanutils 1.6.1
>
> Mark
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org