I have been trying to get Tomcat embedded in my application. The problem I am seeing is that when I attach a root context to the host, it doesn't start because of a null class loader. I have been using an example that I found on the web to start embedded Tomcat; my code is below. I have tried this with Tomcat 5.0.28, 5.5.4 (other problems there), and 5.5.6. 5.0.28 and
5.5.6 exhibit the same behavior. I stepped through the Catalina source code from 5.5.6, and this is what I found: When the root context is started (the start method of StandardContext is called), the call to getLoader() returns null. This seems reasonable. An instance of WebappLoader is created and attached to the StandardContext object by calling setLoader. Line 3917 of org/apache/catalina/core/StandardContext.java if (getLoader() == null) { ClassLoader parent = null; if (getPrivileged()) { if (log.isDebugEnabled()) log.debug("Configuring privileged default Loader"); parent = this.getClass().getClassLoader(); } else { if (log.isDebugEnabled()) log.debug("Configuring non-privileged default Loader"); parent = getParentClassLoader(); } WebappLoader webappLoader = new WebappLoader(parent); webappLoader.setDelegate(getDelegate()); setLoader(webappLoader); Later in the same method, bindThread is called to associate the new class loader with the thread. Line 3970 of org/apache/catalina/core/StandardContext.java ClassLoader oldCCL = bindThread(); The problem I am seeing is that the class loader associated with the WebappLoader object is not created until the start method on the Webapploader object is called, and that method is not called until later in the start method of the StandardContext object. Line 3981 of org/apache/catalina/core/StandardContext.java started = true; // Start our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) ((Lifecycle) loader).start(); if ((logger != null) && (logger instanceof Lifecycle)) ((Lifecycle) logger).start(); Inside the setLoader method of StandardBase, it looks like the loader is started if the context has been started, but the context hasn't been started yet - it happens after bindThread is called as well. What happens in the bindThread class is the class loader returned from WebappLoader's getClassLoader method is null, causing the context class loader in the current thread to be set to null, causing problems downstream. The error I get is at the bottom of this message. I can work around the problem if I change the getClassLoader method in WebappLoader from public ClassLoader getClassLoader() { return ((ClassLoader) classLoader); } to public ClassLoader getClassLoader() { if (classLoader != null) { return ((ClassLoader) classLoader); } else { return ((ClassLoader)parentClassLoader); } } Is there something I am doing wrong in embedding Tomcat in my application or is there a bug here? Here is my code to start up the Embedded class: _tomcat = new Embedded(); String path = new File(ServerProperties.getTomcatPath()).getAbsolutePath(); _tomcat.setCatalinaHome(path); MemoryRealm memRealm = new MemoryRealm(); _tomcat.setRealm(memRealm); // create an Engine Engine baseEngine = _tomcat.createEngine(); baseEngine.setName("Engine"); baseEngine.setDefaultHost("localhost"); // create Host Host baseHost = _tomcat.createHost("localhost", path + "/webapps"); baseEngine.addChild(baseHost); // create root Context Context rootCtx = _tomcat.createContext("", path + "/webapps/ROOT"); rootCtx.setReloadable(false); rootCtx.addWelcomeFile("index.jsp"); baseHost.addChild(rootCtx); // add new Engine to set of Engines for embedded server _tomcat.addEngine(baseEngine); // create Connector Connector httpConnector = _tomcat.createConnector((InetAddress)null, 8080, false); // add new Connector to set of Connectors for embedded server, associated with Engine _tomcat.addConnector(httpConnector); // start operation try { _tomcat.start(); } catch (org.apache.catalina.LifecycleException ex) { // Todo: Handle tomcat exception ex.printStackTrace(); } Here is the exception I get as a result of the null class loader: javax.xml.parsers.FactoryConfigurationError: Provider org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not found at javax.xml.parsers.DocumentBuilderFactory.newInstance(DocumentBuilderFact ory.java:104) at org.apache.commons.modeler.util.DomUtil.readXml(DomUtil.java:284) at org.apache.commons.modeler.modules.MbeansDescriptorsDOMSource.execute(Mb eansDescriptorsDOMSource.java:130) at org.apache.commons.modeler.modules.MbeansDescriptorsDOMSource.loadDescri ptors(MbeansDescriptorsDOMSource.java:120) at org.apache.commons.modeler.Registry.load(Registry.java:819) at org.apache.commons.modeler.Registry.loadDescriptors(Registry.java:931) at org.apache.commons.modeler.Registry.loadDescriptors(Registry.java:909) at org.apache.commons.modeler.Registry.findDescriptor(Registry.java:992) at org.apache.commons.modeler.Registry.findManagedBean(Registry.java:696) at org.apache.commons.modeler.Registry.findManagedBean(Registry.java:1047) at org.apache.commons.modeler.Registry.registerComponent(Registry.java:859) at org.apache.catalina.loader.WebappLoader.init(WebappLoader.java:583) at org.apache.catalina.loader.WebappLoader.start(WebappLoader.java:615) at org.apache.catalina.core.StandardContext.start(StandardContext.java:3985 ) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1011) at org.apache.catalina.core.StandardHost.start(StandardHost.java:718) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1011) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:437) at org.apache.catalina.startup.Embedded.start(Embedded.java:789) Thanks, Tim --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]