You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Marco Pöhler <ma...@poehlerpoehler.de> on 2006/11/08 14:29:18 UTC

Valve using Spring / Classloading problem

Hi list,

I try to write a Valve, that uses a Spring BeanFactory to lookup beans 
and do things. A FactoryBean is initialized when the Valve is called the 
first time. Here is the code for the Valve:

public class TrackingValve extends ValveBase {

    private StorageService storageService;

    private String configFile = "tracking-valve-applicationContext.xml";

    public void invoke(Request request, Response response) throws 
IOException,
            ServletException {

        if (storageService == null) {
            containerLog.info("initialize " + this.getClass().getName()
                    + " using configuration from " + configFile);
            ResourceLoader rl = new DefaultResourceLoader(getClass()
                    .getClassLoader());
            Resource resource = rl.getResource(configFile);
            BeanFactory beanFactory = new XmlBeanFactory(resource);
            storageService = (StorageService) beanFactory
                    .getBean("storageService");
        }

        next.invoke(request, response);

        if (storageService != null) {
            containerLog.info("do something with StorageService  !");
        } else {
            containerLog.error("StorageService lookup failed !");
        }
    }

This Class extending org.apache.catalina.valves.ValveBase, part of 
catalina.jar in server/lib.
Because of the Classloader Hierarchie described here 
http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html#Overview
I created a jar containing my TrackingValve.class and all dependencies 
(spring, implementation of StorageService and many other things) and put 
it in the server/lib. The tracking-valve-applicationContext.xml resides 
in the root folder of the jar.

When starting Tomcat, everthing looks fine. The first call to the valve 
throws an Exception:

stdout.log:
14:16:42,203  INFO (Http11AprProtocol.java:121) - Initializing Coyote 
HTTP/1.1 on http-80
14:16:42,203  INFO (Catalina.java:511) - Initialization processed in 594 ms
14:16:42,218  INFO (StandardService.java:442) - Starting service Catalina
14:16:42,234  INFO (StandardEngine.java:431) - Starting Servlet Engine: 
Apache Tomcat/5.5.17
14:16:42,296  INFO (StandardHost.java:716) - XML validation disabled
14:16:42,968  INFO (Http11AprProtocol.java:151) - Starting Coyote 
HTTP/1.1 on http-80
14:16:42,984  INFO (Catalina.java:559) - Server startup in 781 ms
14:16:48,531 ERROR (CoyoteAdapter.java:157) - An exception or error 
occurred in the container during the request processing
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot 
find class [eu.tuxoo.omt.model.service.impl.StorageServiceImpl] for bean 
with name 'storageService' defined in class path resource 
[tracking-valve-applicationContext.xml]; nested exception is 
java.lang.ClassNotFoundException: 
eu.tuxoo.omt.model.service.impl.StorageServiceImpl
Caused by:
*java.lang.ClassNotFoundException: 
eu.tuxoo.omt.model.service.impl.StorageServiceImpl*
    at 
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1352)
    at 
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1198)
    at org.springframework.util.ClassUtils.forName(ClassUtils.java:177)
    at 
org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:313)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:912)
    at 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:346)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:245)
    at 
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:242)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
    at eu.tuxoo.omt.valve.TrackingValve.invoke(TrackingValve.java:35)
    at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
    at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
    at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
    at 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
    at 
org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:833)
    at 
org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:639)
    at 
org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1285)
    at java.lang.Thread.run(Unknown Source)

catalina.out
08.11.2006 14:16:48 eu.tuxoo.omt.valve.TrackingValve invoke
INFO: initialize eu.tuxoo.omt.valve.TrackingValve using configuration 
from tracking-valve-applicationContext.xml
08.11.2006 14:16:48 org.springframework.core.CollectionFactory <clinit>
INFO: JDK 1.4+ collections available
08.11.2006 14:16:48 
org.springframework.beans.factory.xml.XmlBeanDefinitionReader 
loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource 
[tracking-valve-applicationContext.xml]

The class eu.tuxoo.omt.model.service.impl.StorageServiceImpl is 
definitely in the jar in server/lib. It seems that spring uses the 
WebappClassLoader to instanciate the classes in the bean factory, is 
this the correct classloader to load classes from server/lib ? May be 
this is a Spring problem ?!

Any ideas/suggestions ? ;-)

Thanks in advance

Marco

--
http://www.kontaktlinsen-preisvergleich.de
http://www.tintenpatronen-preisvergleich.de