[Tomcat6.0源码]项目的部署
来源:互联网 发布:北京美特软件 编辑:程序博客网 时间:2024/05/16 06:17
上回说到在HostConfig.start()会部署所有的项目:
public void start() { if (log.isDebugEnabled()) log.debug(sm.getString("hostConfig.start")); try { ObjectName hostON = new ObjectName(host.getObjectName()); oname = new ObjectName (hostON.getDomain() + ":type=Deployer,host=" + host.getName()); Registry.getRegistry(null, null).registerComponent (this, oname, this.getClass().getName()); } catch (Exception e) { log.error(sm.getString("hostConfig.jmx.register", oname), e); } if (host.getDeployOnStartup()) deployApps(); }
HostConfig.deployApps():
/** * Deploy applications for any directories or WAR files that are found * in our "application root" directory. */ protected void deployApps() { File appBase = appBase();//webapps File configBase = configBase();//conf/Catalina/localhost String[] filteredAppPaths = filterAppPaths(appBase.list()); // Deploy XML descriptors from configBase deployDescriptors(configBase, configBase.list()); // Deploy WARs, and loop if additional descriptors are found deployWARs(appBase, filteredAppPaths); // Deploy expanded folders deployDirectories(appBase, filteredAppPaths); }
HostConfig.deployDescriptors();是部署文件夹项目,deployWARs是部署war包的项目,主要过程一样,以HostConfig.deployWARs()为例:
protected void deployWARs(File appBase, String[] files) { if (files == null) return; for (int i = 0; i < files.length; i++) { if (files[i].equalsIgnoreCase("META-INF")) continue; if (files[i].equalsIgnoreCase("WEB-INF")) continue; File dir = new File(appBase, files[i]); if (files[i].toLowerCase().endsWith(".war") && dir.isFile() && !invalidWars.contains(files[i]) ) { // Calculate the context path and make sure it is unique String contextPath = "/" + files[i].replace('#','/'); int period = contextPath.lastIndexOf("."); contextPath = contextPath.substring(0, period); // Check for WARs with /../ /./ or similar sequences in the name if (!validateContextPath(appBase, contextPath)) { log.error(sm.getString( "hostConfig.illegalWarName", files[i])); invalidWars.add(files[i]); continue; } if (contextPath.equals("/ROOT")) contextPath = ""; if (isServiced(contextPath)) continue; String file = files[i]; deployWAR(contextPath, dir, file); } } }
HostConfig.deployWAR():
protected void deployWAR(String contextPath, File war, String file) { if (deploymentExists(contextPath)) return; // Checking for a nested /META-INF/context.xml JarFile jar = null; JarEntry entry = null; InputStream istream = null; BufferedOutputStream ostream = null; File xml = new File (configBase, file.substring(0, file.lastIndexOf(".")) + ".xml"); if (deployXML && !xml.exists()) { try { jar = new JarFile(war); entry = jar.getJarEntry(Constants.ApplicationContextXml); if (entry != null) { istream = jar.getInputStream(entry); configBase.mkdirs(); ostream = new BufferedOutputStream (new FileOutputStream(xml), 1024); byte buffer[] = new byte[1024]; while (true) { int n = istream.read(buffer); if (n < 0) { break; } ostream.write(buffer, 0, n); } ostream.flush(); ostream.close(); ostream = null; istream.close(); istream = null; entry = null; jar.close(); jar = null; } } catch (Exception e) { // Ignore and continue if (ostream != null) { try { ostream.close(); } catch (Throwable t) { ; } ostream = null; } if (istream != null) { try { istream.close(); } catch (Throwable t) { ; } istream = null; } } finally { entry = null; if (jar != null) { try { jar.close(); } catch (Throwable t) { ; } jar = null; } } } DeployedApplication deployedApp = new DeployedApplication(contextPath); // Deploy the application in this WAR file if(log.isInfoEnabled()) log.info(sm.getString("hostConfig.deployJar", file)); try { Context context = null; if (deployXML && xml.exists()) { synchronized (digester) { try { context = (Context) digester.parse(xml); if (context == null) { log.error(sm.getString("hostConfig.deployDescriptor.error", file)); return; } } finally { digester.reset(); } } context.setConfigFile(xml.getAbsolutePath()); } else { context = (Context) Class.forName(contextClass).newInstance(); } // Populate redeploy resources with the WAR file deployedApp.redeployResources.put (war.getAbsolutePath(), new Long(war.lastModified())); if (deployXML && xml.exists()) { deployedApp.redeployResources.put (xml.getAbsolutePath(), new Long(xml.lastModified())); } if (context instanceof Lifecycle) { Class clazz = Class.forName(host.getConfigClass()); LifecycleListener listener = (LifecycleListener) clazz.newInstance(); ((Lifecycle) context).addLifecycleListener(listener); } context.setPath(contextPath); context.setDocBase(file); host.addChild(context); // If we're unpacking WARs, the docBase will be mutated after // starting the context if (unpackWARs && (context.getDocBase() != null)) { String name = null; String path = context.getPath(); if (path.equals("")) { name = "ROOT"; } else { if (path.startsWith("/")) { name = path.substring(1); } else { name = path; } } name = name.replace('/', '#'); File docBase = new File(name); if (!docBase.isAbsolute()) { docBase = new File(appBase(), name); } deployedApp.redeployResources.put(docBase.getAbsolutePath(), new Long(docBase.lastModified())); addWatchedResources(deployedApp, docBase.getAbsolutePath(), context); } else { addWatchedResources(deployedApp, null, context); } } catch (Throwable t) { log.error(sm.getString("hostConfig.deployJar.error", file), t); } deployed.put(contextPath, deployedApp); }
StandardHost.addChild():
/** * Add a child Container, only if the proposed child is an implementation * of Context. * * @param child Child container to be added */ public void addChild(Container child) { if (child instanceof Lifecycle) { ((Lifecycle) child).addLifecycleListener( new MemoryLeakTrackingListener()); } if (!(child instanceof Context)) throw new IllegalArgumentException (sm.getString("standardHost.notContext")); super.addChild(child); }
ContainerBase.addChild():
public void addChild(Container child) { if (Globals.IS_SECURITY_ENABLED) { PrivilegedAction dp = new PrivilegedAddChild(child); AccessController.doPrivileged(dp); } else { addChildInternal(child); } }
ContainerBase.addChildInternal():
private void addChildInternal(Container child) { if( log.isDebugEnabled() ) log.debug("Add child " + child + " " + this); synchronized(children) { if (children.get(child.getName()) != null) throw new IllegalArgumentException("addChild: Child name '" + child.getName() + "' is not unique"); child.setParent(this); // May throw IAE children.put(child.getName(), child); // Start child if (started && startChildren && (child instanceof Lifecycle)) { boolean success = false; try { ((Lifecycle) child).start(); success = true; } catch (LifecycleException e) { log.error("ContainerBase.addChild: start: ", e); throw new IllegalStateException ("ContainerBase.addChild: start: " + e); } finally { if (!success) { children.remove(child.getName()); } } } fireContainerEvent(ADD_CHILD_EVENT, child); } }
((Lifecycle) child).start();即StandardContext.start():
public synchronized void start() throws LifecycleException { //if (lazy ) return; if (started) { if(log.isInfoEnabled()) log.info(sm.getString("containerBase.alreadyStarted", logName())); return; } if( !initialized ) { try { init(); } catch( Exception ex ) { throw new LifecycleException("Error initializaing ", ex); } } if(log.isDebugEnabled()) log.debug("Starting " + ("".equals(getName()) ? "ROOT" : getName())); // Set JMX object name for proper pipeline registration preRegisterJMX(); if ((oname != null) && (Registry.getRegistry(null, null).getMBeanServer().isRegistered(oname))) { // As things depend on the JMX registration, the context // must be reregistered again once properly initialized Registry.getRegistry(null, null).unregisterComponent(oname); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); setAvailable(false); setConfigured(false); boolean ok = true; // Add missing components as necessary if (webappResources == null) { // (1) Required by Loader if (log.isDebugEnabled()) log.debug("Configuring default Resources"); try { if ((docBase != null) && (docBase.endsWith(".war")) && (!(new File(getBasePath())).isDirectory())) setResources(new WARDirContext()); else setResources(new FileDirContext()); } catch (IllegalArgumentException e) { log.error("Error initializing resources: " + e.getMessage()); ok = false; } } if (ok) { if (!resourcesStart()) { log.error( "Error in resourceStart()"); ok = false; } } // Look for a realm - that may have been configured earlier. // If the realm is added after context - it'll set itself. // TODO: what is the use case for this ? if( realm == null && mserver != null ) { ObjectName realmName=null; try { realmName=new ObjectName( getEngineName() + ":type=Realm,host=" + getHostname() + ",path=" + getPath()); if( mserver.isRegistered(realmName ) ) { mserver.invoke(realmName, "init", new Object[] {}, new String[] {} ); } } catch( Throwable t ) { if(log.isDebugEnabled()) log.debug("No realm for this host " + realmName); } } if (getLoader() == null) { WebappLoader webappLoader = new WebappLoader(getParentClassLoader()); webappLoader.setDelegate(getDelegate()); setLoader(webappLoader); } // Initialize character set mapper getCharsetMapper(); // Post work directory postWorkDirectory(); // Validate required extensions boolean dependencyCheck = true; try { dependencyCheck = ExtensionValidator.validateApplication (getResources(), this); } catch (IOException ioe) { log.error("Error in dependencyCheck", ioe); dependencyCheck = false; } if (!dependencyCheck) { // do not make application available if depency check fails ok = false; } // Reading the "catalina.useNaming" environment variable String useNamingProperty = System.getProperty("catalina.useNaming"); if ((useNamingProperty != null) && (useNamingProperty.equals("false"))) { useNaming = false; } if (ok && isUseNaming()) { if (namingContextListener == null) { namingContextListener = new NamingContextListener(); namingContextListener.setName(getNamingContextName()); addLifecycleListener(namingContextListener); } } // Standard container startup if (log.isDebugEnabled()) log.debug("Processing standard container startup"); // Binding thread ClassLoader oldCCL = bindThread(); boolean mainOk = false; try { if (ok) { started = true; // Start our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) ((Lifecycle) loader).start(); // since the loader just started, the webapp classloader is now // created. // By calling unbindThread and bindThread in a row, we setup the // current Thread CCL to be the webapp classloader unbindThread(oldCCL); oldCCL = bindThread(); // Initialize logger again. Other components might have used it too early, // so it should be reset. logger = null; getLogger(); if ((logger != null) && (logger instanceof Lifecycle)) ((Lifecycle) logger).start(); if ((cluster != null) && (cluster instanceof Lifecycle)) ((Lifecycle) cluster).start(); if ((realm != null) && (realm instanceof Lifecycle)) ((Lifecycle) realm).start(); if ((resources != null) && (resources instanceof Lifecycle)) ((Lifecycle) resources).start(); // Start our child containers, if any Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) ((Lifecycle) children[i]).start(); } // Start the Valves in our pipeline (including the basic), // if any if (pipeline instanceof Lifecycle) { ((Lifecycle) pipeline).start(); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(START_EVENT, null); // Acquire clustered manager Manager contextManager = null; if (manager == null) { if ( (getCluster() != null) && distributable) { try { contextManager = getCluster().createManager(getName()); } catch (Exception ex) { log.error("standardContext.clusterFail", ex); ok = false; } } else { contextManager = new StandardManager(); } } // Configure default manager if none was specified if (contextManager != null) { setManager(contextManager); } if (manager!=null && (getCluster() != null) && distributable) { //let the cluster know that there is a context that is distributable //and that it has its own manager getCluster().registerManager(manager); } mainOk = true; } } finally { // Unbinding thread unbindThread(oldCCL); if (!mainOk) { // An exception occurred // Register with JMX anyway, to allow management registerJMX(); } } if (!getConfigured()) { log.error( "Error getConfigured"); ok = false; } // We put the resources into the servlet context if (ok) getServletContext().setAttribute (Globals.RESOURCES_ATTR, getResources()); // Initialize associated mapper mapper.setContext(getPath(), welcomeFiles, resources); // Binding thread oldCCL = bindThread(); // Set annotation processing parameter for Jasper (unfortunately, since // this can be configured in many places and not just in /WEB-INF/web.xml, // there are not many solutions) // Initialize annotation processor if (ok && !getIgnoreAnnotations()) { if (annotationProcessor == null) { if (isUseNaming() && namingContextListener != null) { annotationProcessor = new DefaultAnnotationProcessor(namingContextListener.getEnvContext()); } else { annotationProcessor = new DefaultAnnotationProcessor(null); } } getServletContext().setAttribute (AnnotationProcessor.class.getName(), annotationProcessor); } try { // Create context attributes that will be required if (ok) { postWelcomeFiles(); } // Set up the context init params mergeParameters(); if (ok) { // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); } // Configure and call application event listeners if (ok) { if (!listenerStart()) { log.error( "Error listenerStart"); ok = false; } } try { // Start manager if ((manager != null) && (manager instanceof Lifecycle)) { ((Lifecycle) getManager()).start(); } // Start ContainerBackgroundProcessor thread super.threadStart(); } catch(Exception e) { log.error("Error manager.start()", e); ok = false; } // Configure and call application filters if (ok) { if (!filterStart()) { log.error( "Error filterStart"); ok = false; } } // Load and initialize all "load on startup" servlets if (ok) { loadOnStartup(findChildren()); } } finally { // Unbinding thread unbindThread(oldCCL); } // Set available status depending upon startup success if (ok) { if (log.isDebugEnabled()) log.debug("Starting completed"); setAvailable(true); } else { log.error(sm.getString("standardContext.startFailed", getName())); try { stop(); } catch (Throwable t) { log.error(sm.getString("standardContext.startCleanup"), t); } setAvailable(false); } // JMX registration registerJMX(); startTime=System.currentTimeMillis(); // Send j2ee.state.running notification if (ok && (this.getObjectName() != null)) { Notification notification = new Notification("j2ee.state.running", this.getObjectName(), sequenceNumber++); broadcaster.sendNotification(notification); } // Close all JARs right away to avoid always opening a peak number // of files on startup if (getLoader() instanceof WebappLoader) { ((WebappLoader) getLoader()).closeJARs(true); } // Reinitializing if something went wrong if (!ok && started) { stop(); } //cacheContext(); }
StandardContext.init():
public void init() throws Exception { if( this.getParent() == null ) { ObjectName parentName=getParentName(); if( ! mserver.isRegistered(parentName)) { if(log.isDebugEnabled()) log.debug("No host, creating one " + parentName); StandardHost host=new StandardHost(); host.setName(hostName); host.setAutoDeploy(false); Registry.getRegistry(null, null) .registerComponent(host, parentName, null); // We could do it the hard way... //mserver.invoke(parentName, "init", new Object[] {}, new String[] {} ); // or same thing easier: host.init(); } // Add the main configuration listener LifecycleListener config = null; try { String configClassName = null; try { configClassName = String.valueOf(mserver.getAttribute(parentName, "configClass")); } catch (AttributeNotFoundException e) { // Ignore, it's normal a host may not have this optional attribute } if (configClassName != null) { Class clazz = Class.forName(configClassName); config = (LifecycleListener) clazz.newInstance(); } else { config = new ContextConfig(); } } catch (Exception e) { log.warn("Error creating ContextConfig for " + parentName, e); throw e; } this.addLifecycleListener(config); if (log.isDebugEnabled()) { log.debug("AddChild " + parentName + " " + this); } try { mserver.invoke(parentName, "addChild", new Object[] { this }, new String[] {"org.apache.catalina.Container"}); } catch (Exception e) { destroy(); throw e; } // It's possible that addChild may have started us if( initialized ) { return; } } if (processTlds) { this.addLifecycleListener(new TldConfig()); } super.init(); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(INIT_EVENT, null); // Send j2ee.state.starting notification if (this.getObjectName() != null) { Notification notification = new Notification("j2ee.state.starting", this.getObjectName(), sequenceNumber++); broadcaster.sendNotification(notification); } }
lifecycle.fireLifecycleEvent(INIT_EVENT, null);LifecycleSupport.fireLifecycleEvent():
/** * Notify all lifecycle event listeners that a particular event has * occurred for this Container. The default implementation performs * this notification synchronously using the calling thread. * * @param type Event type * @param data Event data */ public void fireLifecycleEvent(String type, Object data) { if (Lifecycle.INIT_EVENT.equals(type)) { state = "INITIALIZED"; } else if (Lifecycle.BEFORE_START_EVENT.equals(type)) { state = "STARTING_PREP"; } else if (Lifecycle.START_EVENT.equals(type)) { state = "STARTING"; } else if (Lifecycle.AFTER_START_EVENT.equals(type)) { state = "STARTED"; } else if (Lifecycle.BEFORE_STOP_EVENT.equals(type)) { state = "STOPPING_PREP"; } else if (Lifecycle.STOP_EVENT.equals(type)) { state = "STOPPING"; } else if (Lifecycle.AFTER_STOP_EVENT.equals(type)) { state = "STOPPED"; } else if (Lifecycle.DESTROY_EVENT.equals(type)) { state = "DESTROYED"; } LifecycleEvent event = new LifecycleEvent(lifecycle, type, data); LifecycleListener interested[] = listeners; for (int i = 0; i < interested.length; i++) interested[i].lifecycleEvent(event); }
调用所有绑定的监听器的lifecycleEvent()方法,其中有ContextConfig.lifecycleEvent():
public void lifecycleEvent(LifecycleEvent event) { // Identify the context we are associated with try { context = (Context) event.getLifecycle(); } catch (ClassCastException e) { log.error(sm.getString("contextConfig.cce", event.getLifecycle()), e); return; } // Process the event that has occurred if (event.getType().equals(Lifecycle.START_EVENT)) { start(); } else if (event.getType().equals(StandardContext.BEFORE_START_EVENT)) { beforeStart(); } else if (event.getType().equals(StandardContext.AFTER_START_EVENT)) { // Restore docBase for management tools if (originalDocBase != null) { String docBase = context.getDocBase(); context.setDocBase(originalDocBase); originalDocBase = docBase; } } else if (event.getType().equals(Lifecycle.STOP_EVENT)) { if (originalDocBase != null) { String docBase = context.getDocBase(); context.setDocBase(originalDocBase); originalDocBase = docBase; } stop(); } else if (event.getType().equals(Lifecycle.INIT_EVENT)) { init(); } else if (event.getType().equals(Lifecycle.DESTROY_EVENT)) { destroy(); } }
INIT_EVENT参数调用的是ContextConfig.init():
protected void init() { // Called from StandardContext.init() if (webDigester == null){ webDigester = createWebDigester(); webDigester.getParser(); } if (contextDigester == null){ contextDigester = createContextDigester(); contextDigester.getParser(); } if (log.isDebugEnabled()) log.debug(sm.getString("contextConfig.init")); context.setConfigured(false); ok = true; contextConfig(); try { fixDocBase(); } catch (IOException e) { log.error(sm.getString( "contextConfig.fixDocBase", context.getPath()), e); } }
先设置web.xml、context.xml的解析规则,处理默认的配置文件。
createWebDigester()里调用WebRuleSet.addRuleInstances():
digester.addCallMethod(prefix + "web-app/listener/listener-class", "addApplicationListener", 0);
Digester.addCallMethod()方法是解析到listenner-calss节点时,取其值当做addApplicationLister方法的参数。
StandardContext.addApplicationLister():
/** * Add a new Listener class name to the set of Listeners * configured for this application. * * @param listener Java class name of a listener class */ public void addApplicationListener(String listener) { synchronized (applicationListenersLock) { String results[] =new String[applicationListeners.length + 1]; for (int i = 0; i < applicationListeners.length; i++) { if (listener.equals(applicationListeners[i])) { log.info(sm.getString( "standardContext.duplicateListener",listener)); return; } results[i] = applicationListeners[i]; } results[applicationListeners.length] = listener; applicationListeners = results; } fireContainerEvent("addApplicationListener", listener); // FIXME - add instance if already started? }
ContextConfig.fixDocBase():
protected void fixDocBase() throws IOException { Host host = (Host) context.getParent(); String appBase = host.getAppBase(); boolean unpackWARs = true; if (host instanceof StandardHost) { unpackWARs = ((StandardHost) host).isUnpackWARs() && ((StandardContext) context).getUnpackWAR(); } File canonicalAppBase = new File(appBase); if (canonicalAppBase.isAbsolute()) { canonicalAppBase = canonicalAppBase.getCanonicalFile(); } else { canonicalAppBase = new File(System.getProperty("catalina.base"), appBase) .getCanonicalFile(); } String docBase = context.getDocBase(); if (docBase == null) { // Trying to guess the docBase according to the path String path = context.getPath(); if (path == null) { return; } if (path.equals("")) { docBase = "ROOT"; } else { if (path.startsWith("/")) { docBase = path.substring(1).replace('/', '#'); } else { docBase = path.replace('/', '#'); } } } File file = new File(docBase); if (!file.isAbsolute()) { docBase = (new File(canonicalAppBase, docBase)).getPath(); } else { docBase = file.getCanonicalPath(); } file = new File(docBase); String origDocBase = docBase; String pathName = context.getPath(); if (pathName.equals("")) { pathName = "ROOT"; } else { // Context path must start with '/' pathName = pathName.substring(1).replace('/', '#'); } if (docBase.toLowerCase().endsWith(".war") && !file.isDirectory() && unpackWARs) { URL war = new URL("jar:" + (new File(docBase)).toURI().toURL() + "!/"); docBase = ExpandWar.expand(host, war, pathName); file = new File(docBase); docBase = file.getCanonicalPath(); if (context instanceof StandardContext) { ((StandardContext) context).setOriginalDocBase(origDocBase); } } else if (docBase.toLowerCase().endsWith(".war") && !file.isDirectory() && !unpackWARs) { URL war = new URL("jar:" + (new File (docBase)).toURI().toURL() + "!/"); ExpandWar.validate(host, war, pathName); } else { File docDir = new File(docBase); if (!docDir.exists()) { File warFile = new File(docBase + ".war"); if (warFile.exists()) { URL war = new URL("jar:" + warFile.toURI().toURL() + "!/"); if (unpackWARs) { docBase = ExpandWar.expand(host, war, pathName); file = new File(docBase); docBase = file.getCanonicalPath(); } else { docBase = warFile.getCanonicalPath(); ExpandWar.validate(host, war, pathName); } } if (context instanceof StandardContext) { ((StandardContext) context).setOriginalDocBase(origDocBase); } } } if (docBase.startsWith(canonicalAppBase.getPath() + File.separatorChar)) { docBase = docBase.substring(canonicalAppBase.getPath().length()); docBase = docBase.replace(File.separatorChar, '/'); if (docBase.startsWith("/")) { docBase = docBase.substring(1); } } else { docBase = docBase.replace(File.separatorChar, '/'); } context.setDocBase(docBase); }
解压war包,docBase = ExpandWar.expand(host, war, pathName);
/** * Expand the WAR file found at the specified URL into an unpacked * directory structure, and return the absolute pathname to the expanded * directory. * * @param host Host war is being installed for * @param war URL of the web application archive to be expanded * (must start with "jar:") * @param pathname Context path name for web application * * @exception IllegalArgumentException if this is not a "jar:" URL or if the * WAR file is invalid * @exception IOException if an input/output error was encountered * during expansion */ public static String expand(Host host, URL war, String pathname) throws IOException { // Make sure that there is no such directory already existing File appBase = new File(host.getAppBase()); if (!appBase.isAbsolute()) { appBase = new File(System.getProperty("catalina.base"), host.getAppBase()); } if (!appBase.exists() || !appBase.isDirectory()) { throw new IOException (sm.getString("hostConfig.appBase", appBase.getAbsolutePath())); } File docBase = new File(appBase, pathname); if (docBase.exists()) { // War file is already installed return (docBase.getAbsolutePath()); } // Create the new document base directory docBase.mkdir(); // Expand the WAR into the new document base directory String canonicalDocBasePrefix = docBase.getCanonicalPath(); if (!canonicalDocBasePrefix.endsWith(File.separator)) { canonicalDocBasePrefix += File.separator; } JarURLConnection juc = (JarURLConnection) war.openConnection(); juc.setUseCaches(false); JarFile jarFile = null; InputStream input = null; boolean success = false; try { jarFile = juc.getJarFile(); Enumeration jarEntries = jarFile.entries(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = (JarEntry) jarEntries.nextElement(); String name = jarEntry.getName(); File expandedFile = new File(docBase, name); if (!expandedFile.getCanonicalPath().startsWith( canonicalDocBasePrefix)) { // Trying to expand outside the docBase // Throw an exception to stop the deployment throw new IllegalArgumentException( sm.getString("expandWar.illegalPath",war, name)); } int last = name.lastIndexOf('/'); if (last >= 0) { File parent = new File(docBase, name.substring(0, last)); parent.mkdirs(); } if (name.endsWith("/")) { continue; } input = jarFile.getInputStream(jarEntry); // Bugzilla 33636 expand(input, expandedFile); long lastModified = jarEntry.getTime(); if ((lastModified != -1) && (lastModified != 0)) { expandedFile.setLastModified(lastModified); } input.close(); input = null; } success = true; } catch (IOException e) { throw e; } finally { if (!success) { // If something went wrong, delete expanded dir to keep things // clean deleteDir(docBase); } if (input != null) { try { input.close(); } catch (Throwable t) { ; } input = null; } if (jarFile != null) { try { jarFile.close(); } catch (Throwable t) { ; } jarFile = null; } } // Return the absolute path to our new document base directory return (docBase.getAbsolutePath()); }
初始化,配置都已完成,回到StandardContext.start():
lifecycle.fireLifecycleEvent(START_EVENT, null);
将调用ContextConfig.start():
protected synchronized void start() { // Called from StandardContext.start() if (log.isDebugEnabled()) log.debug(sm.getString("contextConfig.start")); // Set properties based on DefaultContext Container container = context.getParent(); if( !context.getOverride() ) { if( container instanceof Host ) { // Reset the value only if the attribute wasn't // set on the context. xmlValidation = context.getXmlValidation(); if (!xmlValidation) { xmlValidation = ((Host)container).getXmlValidation(); } xmlNamespaceAware = context.getXmlNamespaceAware(); if (!xmlNamespaceAware){ xmlNamespaceAware = ((Host)container).getXmlNamespaceAware(); } container = container.getParent(); } } // Process the default and application web.xml files defaultWebConfig(); applicationWebConfig(); if (!context.getIgnoreAnnotations()) { applicationAnnotationsConfig(); } if (ok) { validateSecurityRoles(); } // Configure an authenticator if we need one if (ok) authenticatorConfig(); // Dump the contents of this pipeline if requested if ((log.isDebugEnabled()) && (context instanceof ContainerBase)) { log.debug("Pipeline Configuration:"); Pipeline pipeline = ((ContainerBase) context).getPipeline(); Valve valves[] = null; if (pipeline != null) valves = pipeline.getValves(); if (valves != null) { for (int i = 0; i < valves.length; i++) { log.debug(" " + valves[i].getInfo()); } } log.debug("======================"); } // Make our application available if no problems were encountered if (ok) context.setConfigured(true); else { log.error(sm.getString("contextConfig.unavailable")); context.setConfigured(false); } }
ContextConfig.applicationWebConfig():
/** * Process the application configuration file, if it exists. */ protected void applicationWebConfig() { String altDDName = null; // Open the application web.xml file, if it exists InputStream stream = null; ServletContext servletContext = context.getServletContext(); if (servletContext != null) { altDDName = (String)servletContext.getAttribute( Globals.ALT_DD_ATTR); if (altDDName != null) { try { stream = new FileInputStream(altDDName); } catch (FileNotFoundException e) { log.error(sm.getString("contextConfig.altDDNotFound", altDDName)); } } else { stream = servletContext.getResourceAsStream (Constants.ApplicationWebXml); } } if (stream == null) { if (log.isDebugEnabled()) { log.debug(sm.getString("contextConfig.applicationMissing") + " " + context); } return; } long t1=System.currentTimeMillis(); URL url=null; // Process the application web.xml file synchronized (webDigester) { try { if (altDDName != null) { url = new File(altDDName).toURL(); } else { url = servletContext.getResource( Constants.ApplicationWebXml); } if( url!=null ) { InputSource is = new InputSource(url.toExternalForm()); is.setByteStream(stream); if (context instanceof StandardContext) { ((StandardContext) context).setReplaceWelcomeFiles(true); } webDigester.push(context); webDigester.setErrorHandler(new ContextErrorHandler()); if(log.isDebugEnabled()) { log.debug("Parsing application web.xml file at " + url.toExternalForm()); } webDigester.parse(is); if (parseException != null) { ok = false; } } else { log.info("No web.xml, using defaults " + context ); } } catch (SAXParseException e) { log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e); log.error(sm.getString("contextConfig.applicationPosition", "" + e.getLineNumber(), "" + e.getColumnNumber())); ok = false; } catch (Exception e) { log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e); ok = false; } finally { webDigester.reset(); parseException = null; try { if (stream != null) { stream.close(); } } catch (IOException e) { log.error(sm.getString("contextConfig.applicationClose"), e); } } } webRuleSet.recycle(); long t2=System.currentTimeMillis(); if (context instanceof StandardContext) { ((StandardContext) context).setStartupTime(t2-t1); } }
解析规则的栈底将是StandardContext对象,解析web.xml
webDigester.push(context);
webDigester.parse(is);
启动web.xml配置文件中的listener:
// Configure and call application event listeners if (ok) { if (!listenerStart()) { log.error( "Error listenerStart"); ok = false; } }
StandardContext.listenerStart():
/** * Configure the set of instantiated application event listeners * for this Context. Return <code>true</code> if all listeners wre * initialized successfully, or <code>false</code> otherwise. */ public boolean listenerStart() { if (log.isDebugEnabled()) log.debug("Configuring application event listeners"); // Instantiate the required listeners ClassLoader loader = getLoader().getClassLoader(); String listeners[] = findApplicationListeners(); Object results[] = new Object[listeners.length]; boolean ok = true; for (int i = 0; i < results.length; i++) { if (getLogger().isDebugEnabled()) getLogger().debug(" Configuring event listener class '" + listeners[i] + "'"); try { Class clazz = loader.loadClass(listeners[i]); results[i] = clazz.newInstance(); // Annotation processing if (!getIgnoreAnnotations()) { getAnnotationProcessor().processAnnotations(results[i]); getAnnotationProcessor().postConstruct(results[i]); } } catch (Throwable t) { getLogger().error (sm.getString("standardContext.applicationListener", listeners[i]), t); ok = false; } } if (!ok) { getLogger().error(sm.getString("standardContext.applicationSkipped")); return (false); } // Sort listeners in two arrays ArrayList eventListeners = new ArrayList(); ArrayList lifecycleListeners = new ArrayList(); for (int i = 0; i < results.length; i++) { if ((results[i] instanceof ServletContextAttributeListener) || (results[i] instanceof ServletRequestAttributeListener) || (results[i] instanceof ServletRequestListener) || (results[i] instanceof HttpSessionAttributeListener)) { eventListeners.add(results[i]); } if ((results[i] instanceof ServletContextListener) || (results[i] instanceof HttpSessionListener)) { lifecycleListeners.add(results[i]); } } setApplicationEventListeners(eventListeners.toArray()); setApplicationLifecycleListeners(lifecycleListeners.toArray()); // Send application start events if (getLogger().isDebugEnabled()) getLogger().debug("Sending application start events"); Object instances[] = getApplicationLifecycleListeners(); if (instances == null) return (ok); ServletContextEvent event = new ServletContextEvent(getServletContext()); for (int i = 0; i < instances.length; i++) { if (instances[i] == null) continue; if (!(instances[i] instanceof ServletContextListener)) continue; ServletContextListener listener = (ServletContextListener) instances[i]; try { fireContainerEvent("beforeContextInitialized", listener); listener.contextInitialized(event); fireContainerEvent("afterContextInitialized", listener); } catch (Throwable t) { fireContainerEvent("afterContextInitialized", listener); getLogger().error (sm.getString("standardContext.listenerStart", instances[i].getClass().getName()), t); ok = false; } } return (ok); }
启动web.xml配置文件中的filter:
// Configure and call application filters if (ok) { if (!filterStart()) { log.error( "Error filterStart"); ok = false; } }
StandardContext.filterStart():
/** * Configure and initialize the set of filters for this Context. * Return <code>true</code> if all filter initialization completed * successfully, or <code>false</code> otherwise. */ public boolean filterStart() { if (getLogger().isDebugEnabled()) getLogger().debug("Starting filters"); // Instantiate and record a FilterConfig for each defined filter boolean ok = true; synchronized (filterConfigs) { filterConfigs.clear(); Iterator names = filterDefs.keySet().iterator(); while (names.hasNext()) { String name = (String) names.next(); if (getLogger().isDebugEnabled()) getLogger().debug(" Starting filter '" + name + "'"); ApplicationFilterConfig filterConfig = null; try { filterConfig = new ApplicationFilterConfig (this, (FilterDef) filterDefs.get(name)); filterConfigs.put(name, filterConfig); } catch (Throwable t) { getLogger().error (sm.getString("standardContext.filterStart", name), t); ok = false; } } } return (ok); }
其实就是创建Filter配置信息的对象,并未创建Filter实例。而至于要start多少监听器,那就得看项目的web.xml了。
- [Tomcat6.0源码]项目的部署
- Tomcat6.0项目的部署问题
- Tomcat6.0项目安装部署(全)
- tomcat6源码的启动和部署工程备注
- Tomcat6.0下drools-jbrms的部署
- eclipse使用Ant组件自动部署项目到tomcat6.0
- 将Tomcat6源码转成可运行的Eclipse项目
- 将Tomcat6源码转成可运行的Eclipse项目(转)
- [Tomcat6.0源码]强大的Digester
- [Tomcat6.0源码]组件的实例化
- [Tomcat6.0源码]组件的初始化
- [Tomcat6.0源码]组件的启动
- [Tomcat6.0源码]设计模式的使用
- Maven项目部署到tomcat6(内嵌tomcat6)
- Tomcat6.0源码学习
- JBPM4项目和tomcat6.0的兼容问题
- JBPM4项目和tomcat6.0的兼容问题
- JBPM4项目和tomcat6.0的兼容问题
- HDU 3938 Portal(离线+Kruskal+并查集)
- android中的invalidate()和postInvalidate()
- 通过Ftp put命令上传导致文件损坏的解决办法
- POJ2488
- js实现页面标题闪烁
- [Tomcat6.0源码]项目的部署
- mysql command line client 打不开(闪一下消失)的解决办法
- STM32的I2C难点(值得慢慢研究)
- 12个固态硬盘优化技巧,延长固态硬盘使用寿命
- pthread_cancel
- Struts2拦截器属性excludeMethods、includeMethods配置无效之解决方法
- Linux操作系统目录配置标准FHS详细介绍
- IOS开发之UIView动画效果的实现
- 查看iptables状态-重启