Noisy Spring JAR

Debugging a Quietly failing Sakai

From a post on sakai-dev by Josh Holtzman:

When spring's DefaultListableBeanFactory (a superclass of a ClassPathApplicationContext, which is at the heart of Sakai's ComponentManager implementation) fails to pre-instantiate all of it's singleton beans, it immediately destroys all of them to ensure that they aren't hanging around in a bad state. This makes sense, but in 1.2.6 the cleanup is implemented in a very quiet way. No logging, no stacktraces, nothing.

In order to debug why my component manager was failing to start up on my machine, I edited DefaultListableBeanFactory so it would be a little noisier about why it was immediately destroying all of its singletons. I'll post this on the spring forums somewhere to see if they're interested in incorporating this change (who knows, they may have already made a similar change). In the meantime, I'm attaching a jar that you can use to replace the stock spring-1.2.6.jar in your tomcat's shared/lib, just in case you find yourself in the uncomfortable position of debugging a quietly failing component manager.

spring-1.2.6-noisy-destruction.jar (MD5: a5184f018fa1f44ce663d6790141d5b5)

spring-1.2.8-noisy-destruction.jar

Or, if you want to make the change yourself (probably a smart move... who knows what nefarious code I've put into this jar!) the (modified) method in question is here:

public void preInstantiateSingletons() throws BeansException {
if (logger.isInfoEnabled()) {
    logger.info("Pre-instantiating singletons in factory [" + this + "]");
}
try {
    for (Iterator it = this.beanDefinitionNames.iterator();
    it.hasNext(); ) {
        String beanName = (String) it.next();
        if (containsBeanDefinition(beanName)) {
            RootBeanDefinition bd =
            getMergedBeanDefinition(beanName, false);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (bd.hasBeanClass() && FactoryBean.class.isAssignableFrom (bd.getBeanClass())) {
                    FactoryBean factory = (FactoryBean)
                    getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (factory.isSingleton()) {                         
                        getBean(beanName);                     
                    }
                }
                else {                     
                    getBean(beanName);                 
                }
            }
        }
    }
}
catch (BeansException ex) {
// destroy already created singletons to avoid dangling resources
    try {         
        logger.error("Failed to preinstantiate a singleton. Destroying all spring beans.");         
        ex.printStackTrace();         
        destroySingletons();     
    }
    catch (Throwable ex2) {         
        logger.error("Pre-instantiating singletons failed, " + "and couldn't destroy already created singletons", ex2);     
    }
    throw ex;
}
}
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.