commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Phil Steitz <>
Subject Re: [logging, beanutils, others] Initial proposal for java.lang.ContextClassLoaderLocal or java.lang.Singleton
Date Mon, 21 Mar 2005 00:27:21 GMT
Simon Kitching wrote:

>Hi All,
>After working on issues in commons-beanutils and commons-logging linked
>to behaviour within j2ee-style environments, I've come to the conclusion
>that there is currently *no* way to correctly implement the Singleton
>pattern within code that might be deployed in a j2ee-style environment.
>This is rather disconcerting. 
>I believe there is a way, though, that the standard Java library could
>be enhanced to make this possible. In other words, a proposal would need
>to be submitted as an enhancement to java via the Java Community
>Process. Could people please have a look at this and tell me whether
>they think I'm right or that they think I'm nuts?
>The doc is here:
I don't claim to be an expert on any of this and I have not followed all 
of the JCL and BeanUtils threads,  so take these as comments from the 
peanut gallery.  I like the idea in the proposal, but I am not sure that 
the specific application is separating concerns correctly.  Maybe 
answering the questions below will help me understand what is going on.

The doc and your previous posts refer to "deployment" and "undeployment" 
as the events leading to initialization and cleanup.  This sounds funny 
to me, because these are relatively rare events - when new or modified 
components are deployed to the server or components are removed.   I 
assume that what you really mean is container startup / shutdown 
events.  Am I correct here?

Assuming startup/shutdown is what we need to worry about, then whether 
we have a problem, and what kind it is, depends on whether the 
initialization and cleanup activities can be triggered by J2EE component 
lifecycle events.  As Craig pointed out, web application shutdown can be 
detected by a ServletContextListener.  Individual servlets get destroy() 
events when they are unloaded and EJBs also get lifecycle events.  Where 
do the things that we need to worry about "live" in J2EE applications 
and why can't they just expose management APIs that get trigerred by 
J2EE component lifecycle events?  This is probably where I am not 
understanding the problem.  Could it be that part of the problem has to 
do with container code itself (i.e, the thingies spawning singletons are 
used by the containers directly)?

I can see the general value of the ContextClassLoaderLocal concept, but 
I am not sure that for things like BeanUtils instance isolation in J2EE 
containers this is the best way to go.  What I am struggling with is why 
in a J2EE container environment we would not just use JNDI or servlet- 
or EJB-local references to house the singletons and lifecycle events to 
initialize and clean them up.  Perhaps ironically, under the covers 
tomcat's JNDI provider maps JNDI contexts to classloaders.  Seems to me 
that the web app developer should be thinking about the JNDI context, 
not the classloader.   I understand that BeanUtils is trying to make 
things easier for web app developers by hardwiring the mapping for them, 
but somehow that just doesn't seem right to me.  What am I missing? 


>I've also been pondering the idea of a commons-singleton project. The
>approach would be to provide something like the following. Note that I
>haven't put a *whole* lot of analysis into this idea yet, and there
>might be some fatal flaw. I'm only posting this idea now because we're
>actively discussing related topics for commons-logging 1.0.5 and I'll be
>away for the next three weeks.
>public class org.apache.commons.singleton.Singleton {
>  /**
>   * Provide an algorithm for correctly storing and retrieving
>   * Singleton objects. Applications running in different environments
>   * (eg different j2ee containers) may need to use different approaches
>   * to correctly implement the Singleton pattern. If a strategy is
>   * set here, then it is used when the getSingleton and setSingleton
>   * methods of this class are invoked. 
>   * <p>
>   * If this method is not called (or null is passed), then this class
>   * will try to guess an appropriate strategy for storing Singletons.
>   */
>  public void setSingletonStrategy(SingletonStrategy s);
>  /**
>   * Return an instance of the specified class which is unique to
>   * the current webapp.
>   */
>  public Object getSingleton(Class c);
> /**
>  * Save the specified object instance as the singleton instance
>  * for the specified class. 
>  *
>  * It is expected that "o instanceof c" is true.
>  */
>  public void setSingleton(Object o, Class c);
>The get/set singleton code would try to determine the correct way of
>saving a singleton using something like the following algorithm. Note
>that the o.a.c.s.Singleton class might have been loaded by a child or
>shared classloader.
> * if a strategy has been set, use it.
> * if Thread.currentThread.getContextClassLoader returns the same
>   object as ClassLoader.getSystemClassLoader, then we are running
>   in a plain app environment (not a j2ee or similar environment), 
>   so just store the singleton in a Map which is a static member of
>   this class.
> * if Thread.currentThread.getContextClassLoader() returns an object
>   which implements "ContextClassLoaderLocal" then store the singleton
>   against that classloader (see the proposal above for adding this
>   functionality to java core).
> * try various container-specific mechanisms for registering an
>   "undeploy" of the context classloader. If it *is* possible to somehow
>   get notification of undeploy of the component whose classloader is
>   Thread.currentThread().getContextClassLoader(), then simply add an
>   entry to a static map keyed by the current context-classloader, and
>   ensure that when that context-classloader is undeployed the map entry
>   is cleared.
> * throw an exception. This ensures that an app that uses singletons
>   fails visibly rather than silently fails to work correctly. The
>   deployer is then forced to provide an explicit singleton storage
>   strategy.
>Note that if all commons libraries that need singletons were to use this
>common o.a.c.singleton.Singleton class, then users would need to
>configure a singleton storage strategy only once.
>To unsubscribe, e-mail:
>For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message