Hi Adrian,

On Wed, 2005-07-27 at 20:15 -0400, Adrian Brock wrote:
> On Wed, 2005-07-27 at 19:43, Simon Kitching wrote:
> > I feel that it is simply unacceptable to drop thirdparty libraries that
> > have never expected to be "container extensions" into the container's
> > classpath? 
> 
> So aren't you just saying don't use commons-logging in infrastructure
> software unless you can isolate that part of the infrastruture
> from sharing any classes with the rest of the server?
> i.e. don't use it an application server like Tomcat/JBoss

Not at all. I'm saying that any code deployed into the container's
classpath should be container-aware or that the container should be
aware of it or both.

Tomcat uses commons-logging, and that's fine because Tomcat ensures that
it cleans up commons-logging when an app is undeployed (see
org.apache.catalina.loader.WebappClassLoader). [1]

If jboss wants to use Hibernate as part of the container, and Hibernate
uses commons-logging then that's fine: but the container needs to take
that into account by ensuring LogFactory.release is called on undeploy.
Yes it would be nice if this wasn't necessary but as I described earlier
neither java nor j2ee provide *any* mechanism for arbitrary code in the
container's classpath to associated resources with a component
("application context") so commons-logging can't easily do this itself.

But I think people should *not* expect that they can grab any random
open-source library from the internet, drop it into the container's
classpath and expect things to work properly. Such libraries should go
into the component's WEB-INF/lib unless they are explicitly declared to
be "container extensions". NB: this includes dropping hibernate into the
container classpath of some arbitrary container framework (j2ee or
otherwise).

Commons-logging only qualifies as a valid "container extension" when the
container ensures that LogFactory.release is called on webapp undeploy.

One interesting problem with many libraries that use logging is that
they do this:
  public class Foo {
    private static final Logger log = Logger.getLogger("somecategory");
  }
The problem occurs if the getLogger method uses the TCCL to determine
what Log object to return. In the case of log4j, if the Context
Repository Selector is configured for log4j then this problem occurs.
Commons-logging has the same limitation.

When such code is in a component's classpath everything is fine. But
when such code is placed into the container's classpath the *first*
component to call it determines what Log object is returned, then when
other components call into that code in the shared classpath the wrong
logger gets used. Again it's back to that static caching issue: using
statics is fine when the class is deployed *via the component* but wrong
when the class is deployed via a shared classloader.

[1] I noticed another interesting little bit of code in tomcat;s
WebappClassLoader.stop method:
     // Clear the classloader reference in common-logging
     org.apache.commons.logging.LogFactory.release(this);
     // Clear the classloader reference in the VM's bean introspector
     java.beans.Introspector.flushCaches();
The introspector class caches stuff at a global level?? eek! Again this
would be a very nice case for attaching such cached info to a specific
classloader to avoid these kinds of bidirectional links...

> 
> I personally don't like this argument. It would lead to 100 applications
> with 100 copies of Xerces (lots of memory footprint) just in case
> it had a memory leak.

Well, xml parsing is part of the j2ee spec so this is a different issue
from people tossing any old library into the classpath.

But if a container bundles xerces then I would expect the container
provider to read the xerces documentation to make sure xerces is known
to be safe in such an environment and that there is nothing extra that
xerces requires in order to run correctly in that setup. As it happens,
I don't know of any such issues but I don't think such assumptions
should be made. See the java.beans.Introspector note above!


> And those "applications" in the case of infrastructure couldn't pass
> DOM objects around without serializing/deserializing them.

Sorry, I don't follow this one. As mentioned above, j2ee servers provide
xml parsers by definition so apps don't (and shouldn't) bundle them.

Are you perhaps talking about some scenario where:
* there is an interface I1 defined in a shared classpath
* app1 creates a concrete instance of interface I1, using a class
  loaded from the local path
* app1 then performs a JNDI lookup or similar to get a reference to
  some method of an object residing in app2 in the same JVM,
  where that method takes an I1 as a parameter
* app1 then calls that external object passing its local instance
* app2 then caches a reference to the parameter
* app1 then leaks on deploy because app2 has a reference to an object
  which has a class loaded from app1's classloader thereby retaining
  app1's classloader including all the other classes.

You know far more about j2ee than I do, so I'll let you tell me whether
this is a common scenario. Certainly ensuring that the implementation of
I1 is in the container's path rather than in the component's path would
solve this. But that whole setup sounds dodgy to me, and rather
unlikely. And pushing up the shared implementation classes into a common
classloader feels more like a workaround for a broken design than a
valid architecture. 

But if this *is* a common usage scenario then I agree I would have to
rethink my posting.

> 
> Hopefully, these problems will go away in JSE7 with a better
> definition of java modularization:
> http://www.jcp.org/en/jsr/detail?id=277
> 

Hmm..interesting. Thanks for the link.

Regards,

Simon



-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO September
19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
hibernate-devel mailing list
hibernate-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/hibernate-devel

Reply via email to