标签:
s1)这两个应用程序所使用到的类文件都位于 %CATALINA_HOME%/server/webapps 目录下,并且分别使用了两个描述符文件:manager.xml and admin.xml;(干货——描述符文件:manager.xml and admin.xml)s2)在tomcat4中, 在%CATALINA_HOME%/server/webapps 目录下,有3个描述符文件;s3)在tomcat5中,分别位于 %CATALINA_HOME%/server/webapps/admin 目录 和 %CATALINA_HOME%/server/webapps/manager 目录下;
3.1)安装Context实例的意思是:创建一个 StandardContext实例,将该实例添加到Host实例中;创建的Context实例会随其父容器——Host实例一起启动。3.2)部署器也可以单独地启动和关闭Context实例;public final class Bootstrap { public static void main(String[] args) { System.setProperty("catalina.base", System.getProperty("user.dir")); Connector connector = new HttpConnector(); Context context = new StandardContext(); // StandardContext's start method adds a default mapper context.setPath("/app1"); context.setDocBase("app1"); LifecycleListener listener = new ContextConfig(); ((Lifecycle) context).addLifecycleListener(listener); Host host = new StandardHost(); host.addChild(context); //highlight line.将StandardContext实例添加到 Host实例中. host.setName("localhost"); host.setAppBase("webapps"); Loader loader = new WebappLoader(); context.setLoader(loader); connector.setContainer(host); try { connector.initialize(); ((Lifecycle) connector).start(); ((Lifecycle) host).start(); Container[] c = context.findChildren(); int length = c.length; for (int i=0; i<length; i++) { Container child = c[i]; System.out.println(child.getName()); } // make the application wait until we press a key. System.in.read(); ((Lifecycle) host).stop(); } catch (Exception e) { e.printStackTrace(); } } }
digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));
public void addRuleInstances(Digester digester) { //org.apache.catalina.startup.HosRuleSet.addRuleInstances(). digester.addObjectCreate(prefix + "Host", "org.apache.catalina.core.StandardHost", "className"); digester.addSetProperties(prefix + "Host"); digester.addRule(prefix + "Host", new CopyParentClassLoaderRule(digester)); digester.addRule(prefix + "Host", new LifecycleListenerRule (digester, "org.apache.catalina.startup.HostConfig", // highlight line. "hostConfigClass")); //...... }
A1)当 在 server.xml 文件中遇到符合 "Server/Service/Engine/Host" 模式的标签时:会创建 org.apache.catalina.startup.HostConfig 类的一个实例,并将其添加到 Host实例中,作为生命周期监听器;
A2)that‘s to say, HostConfig 类会处理 StandardHost.start()方法 和 stop()方法的触发事件;
<?xml version='1.0' encoding='utf-8'?> <!--conf/server.xml源码如下 --> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- Note: A "Server" is not itself a "Container", so you may not define subcomponents such as "Valves" at this level. Documentation at /docs/config/server.html --> <Server port="8005" shutdown="SHUTDOWN"> <!-- Security listener. Documentation at /docs/config/listeners.html <Listener className="org.apache.catalina.security.SecurityListener" /> --> <!--APR library loader. Documentation at /docs/apr.html --> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html --> <Listener className="org.apache.catalina.core.JasperListener" /> <!-- Prevent memory leaks due to use of particular java/javax APIs--> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <!-- Global JNDI resources Documentation at /docs/jndi-resources-howto.html --> <GlobalNamingResources> <!-- Editable user database that can also be used by UserDatabaseRealm to authenticate users --> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <!-- A "Service" is a collection of one or more "Connectors" that share a single "Container" Note: A "Service" is not itself a "Container", so you may not define subcomponents such as "Valves" at this level. Documentation at /docs/config/service.html --> <Service name="Catalina"> <!--The connectors can use a shared executor, you can define one or more named thread pools--> <!-- <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/> --> <!-- A "Connector" represents an endpoint by which requests are received and responses are returned. Documentation at : Java HTTP Connector: /docs/config/http.html (blocking & non-blocking) Java AJP Connector: /docs/config/ajp.html APR (HTTP/AJP) Connector: /docs/apr.html Define a non-SSL HTTP/1.1 Connector on port 8080 --> <Connector port="8888" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- A "Connector" using the shared thread pool--> <!-- <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> --> <!-- Define a SSL HTTP/1.1 Connector on port 8443 This connector uses the JSSE configuration, when using APR, the connector should be using the OpenSSL style configuration described in the APR documentation --> <!-- <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> --> <!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <!-- An Engine represents the entry point (within Catalina) that processes every request. The Engine implementation for Tomcat stand alone analyzes the HTTP headers included with the request, and passes them on to the appropriate Host (virtual host). Documentation at /docs/config/engine.html --> <!-- You should set jvmRoute to support load-balancing via AJP ie : <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> --> <Engine name="Catalina" defaultHost="localhost"> <!--For clustering, please take a look at documentation at: /docs/cluster-howto.html (simple how to) /docs/config/cluster.html (reference documentation) --> <!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> --> <!-- Use the LockOutRealm to prevent attempts to guess user passwords via a brute-force attack --> <Realm className="org.apache.catalina.realm.LockOutRealm"> <!-- This Realm uses the UserDatabase configured in the global JNDI resources under the key "UserDatabase". Any edits that are performed against this UserDatabase are immediately available for use by the Realm. --> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html --> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> </Server>
public void lifecycleEvent(LifecycleEvent event) { //org.apache.catalina.startup.HostConfig.lifecycleEvent(). // Identify the host we are associated with try { host = (Host) event.getLifecycle(); if (host instanceof StandardHost) { int hostDebug = ((StandardHost) host).getDebug(); if (hostDebug > this.debug) { this.debug = hostDebug; } setDeployXML(((StandardHost) host).isDeployXML()); setLiveDeploy(((StandardHost) host).getLiveDeploy()); setUnpackWARs(((StandardHost) host).isUnpackWARs()); } } catch (ClassCastException e) { log(sm.getString("hostConfig.cce", event.getLifecycle()), e); return; } // Process the event that has occurred if (event.getType().equals(Lifecycle.START_EVENT)) start(); // highlight line. else if (event.getType().equals(Lifecycle.STOP_EVENT)) stop(); // highlight line. }
A1)setDeployXML方法:指明了Host实例是否需要部署一个 Context实例的描述符文件;public void setDeployXML(boolean deployXML) { this.deployXML= deployXML; }A2)setLiveDeploy方法:指明了Host实例 是否需要周期性检查一个新的 部署;public void setLiveDeploy(boolean liveDeploy) { this.liveDeploy = liveDeploy; }A3)setUnpackWARs方法:指定是要将WAR 文件形式的web 应用程序解压缩;public void setUnpackWARs(boolean unpackWARs) { this.unpackWARs = unpackWARs; }
protected void start() { //org.apache.catalina.startup.HostConfig.start(). if (debug >= 1) log(sm.getString("hostConfig.start")); if (host.getAutoDeploy()) { deployApps(); } if (isLiveDeploy()) { threadStart(); } } protected void stop() { if (debug >= 1) log(sm.getString("hostConfig.stop")); threadStop(); undeployApps(); }
A1)若autoDeploy为true时: start()方法调用deployApps()方法;protected void deployApps() { if (!(host instanceof Deployer)) return; if (debug >= 1) log(sm.getString("hostConfig.deploying")); File appBase = appBase(); // highlight line. if (!appBase.exists() || !appBase.isDirectory()) return; String files[] = appBase.list(); deployDescriptors(appBase, files); deployWARs(appBase, files); deployDirectories(appBase, files); }protected File appBase() { File file = new File(host.getAppBase()); if (!file.isAbsolute()) file = new File(System.getProperty("catalina.base"), host.getAppBase()); return (file); }A2)若liveDeploy为true时:start()方法调用threadStart()方法;
protected void deployApps() { //org.apache.catalina.startup.HostConfig.deployApps(). if (!(host instanceof Deployer)) return; if (debug >= 1) log(sm.getString("hostConfig.deploying")); File appBase = appBase(); if (!appBase.exists() || !appBase.isDirectory()) return; String files[] = appBase.list(); deployDescriptors(appBase, files); //highlight line. deployWARs(appBase, files); //highlight line. deployDirectories(appBase, files); //highlight line. }
A1)该方法会获取host的实例的appBase属性的值,默认为 webapps 的值(参见 server.xml);部署进程会将 %CATALINA_HOME%/webapps 目录下的所有目录都看做是 web 应用程序的目录来执行部署工作。此外,该目录中所有的WAR 文件和描述符文件也都会进行部署;(干货——想想以前总是要把项目打个war 包,放到webapps 目录下,我在这里找到了答案。)A2)deployApps()方法会调用其他3个方法:deployDescriptors方法,deployWARs方法,deployDirectories方法;
A2.1)deployDescriptors方法:protected void deployDescriptors(File appBase, String[] files) { if (!deployXML) return; for (int i = 0; i < files.length; i++) { if (files[i].equalsIgnoreCase("META-INF")) continue; if (files[i].equalsIgnoreCase("WEB-INF")) continue; if (deployed.contains(files[i])) continue; File dir = new File(appBase, files[i]); if (files[i].toLowerCase().endsWith(".xml")) { deployed.add(files[i]); // Calculate the context path and make sure it is unique String file = files[i].substring(0, files[i].length() - 4); String contextPath = "/" + file; if (file.equals("ROOT")) { contextPath = ""; } if (host.findChild(contextPath) != null) { continue; } // Assume this is a configuration descriptor and deploy it log(sm.getString("hostConfig.deployDescriptor", files[i])); try { URL config = new URL("file", null, dir.getCanonicalPath()); ((Deployer) host).install(config, null); } catch (Throwable t) { log(sm.getString("hostConfig.deployDescriptor.error", files[i]), t); } } } }A2.2)deployWARs方法:protected void deployWARs(File appBase, String[] files) { for (int i = 0; i < files.length; i++) { if (files[i].equalsIgnoreCase("META-INF")) continue; if (files[i].equalsIgnoreCase("WEB-INF")) continue; if (deployed.contains(files[i])) continue; File dir = new File(appBase, files[i]); if (files[i].toLowerCase().endsWith(".war")) { deployed.add(files[i]); // Calculate the context path and make sure it is unique String contextPath = "/" + files[i]; int period = contextPath.lastIndexOf("."); if (period >= 0) contextPath = contextPath.substring(0, period); if (contextPath.equals("/ROOT")) contextPath = ""; if (host.findChild(contextPath) != null) continue; if (isUnpackWARs()) { // Expand and deploy this application as a directory log(sm.getString("hostConfig.expand", files[i])); try { URL url = new URL("jar:file:" + dir.getCanonicalPath() + "!/"); String path = ExpandWar.expand(host,url); url = new URL("file:" + path); ((Deployer) host).install(contextPath, url); } catch (Throwable t) { log(sm.getString("hostConfig.expand.error", files[i]), t); } } else { // Deploy the application in this WAR file log(sm.getString("hostConfig.deployJar", files[i])); try { URL url = new URL("file", null, dir.getCanonicalPath()); url = new URL("jar:" + url.toString() + "!/"); ((Deployer) host).install(contextPath, url); } catch (Throwable t) { log(sm.getString("hostConfig.deployJar.error", files[i]), t); } } } } }A2.3)deployDirectories方法:protected void deployDirectories(File appBase, String[] files) { for (int i = 0; i < files.length; i++) { if (files[i].equalsIgnoreCase("META-INF")) continue; if (files[i].equalsIgnoreCase("WEB-INF")) continue; if (deployed.contains(files[i])) continue; File dir = new File(appBase, files[i]); if (dir.isDirectory()) { deployed.add(files[i]); File webInf = new File(dir, "/WEB-INF"); if (!webInf.exists() || !webInf.isDirectory() || !webInf.canRead()) continue; // Calculate the context path and make sure it is unique String contextPath = "/" + files[i]; if (files[i].equals("ROOT")) contextPath = ""; if (host.findChild(contextPath) != null) continue; // Deploy the application in this directory log(sm.getString("hostConfig.deployDir", files[i])); try { URL url = new URL("file", null, dir.getCanonicalPath()); ((Deployer) host).install(contextPath, url); } catch (Throwable t) { log(sm.getString("hostConfig.deployDir.error", files[i]), t); } } } }
<!-- tomcat4下的admin.xml 文件(\container\webapps\admin)--> <Context path="/admin" docBase="../server/webapps/admin" debug="0" privileged="true"> <!-- Uncomment this Valve to limit access to the Admin app to localhost for obvious security reasons. Allow may be a comma-separated list of hosts (or even regular expressions). <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127.0.0.1"/> --> <Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_admin_log." suffix=".txt" timestamp="true"/> </Context> <!-- tomcat5下的 manager.xml 文件(\container\webapps\manager --> <Context docBase="${catalina.home}/server/webapps/manager" privileged="true" antiResourceLocking="false" antiJARLocking="false" useHttpOnly="true"> <!-- Link to the user database we will get roles from --> <ResourceLink name="users" global="UserDatabase" type="org.apache.catalina.UserDatabase"/> </Context>
protected void deployWARs(File appBase, String[] files) { for (int i = 0; i < files.length; i++) { if (files[i].equalsIgnoreCase("META-INF")) continue; if (files[i].equalsIgnoreCase("WEB-INF")) continue; if (deployed.contains(files[i])) continue; File dir = new File(appBase, files[i]); if (files[i].toLowerCase().endsWith(".war")) { deployed.add(files[i]); // Calculate the context path and make sure it is unique String contextPath = "/" + files[i]; int period = contextPath.lastIndexOf("."); if (period >= 0) contextPath = contextPath.substring(0, period); if (contextPath.equals("/ROOT")) contextPath = ""; if (host.findChild(contextPath) != null) continue; if (isUnpackWARs()) { // Expand and deploy this application as a directory log(sm.getString("hostConfig.expand", files[i])); try { URL url = new URL("jar:file:" + dir.getCanonicalPath() + "!/"); String path = ExpandWar.expand(host,url); url = new URL("file:" + path); ((Deployer) host).install(contextPath, url); } catch (Throwable t) { log(sm.getString("hostConfig.expand.error", files[i]), t); } } else { // Deploy the application in this WAR file log(sm.getString("hostConfig.deployJar", files[i])); try { URL url = new URL("file", null, dir.getCanonicalPath()); url = new URL("jar:" + url.toString() + "!/"); ((Deployer) host).install(contextPath, url); } catch (Throwable t) { log(sm.getString("hostConfig.deployJar.error", files[i]), t); } } } } }
protected void deployDirectories(File appBase, String[] files) { for (int i = 0; i < files.length; i++) { if (files[i].equalsIgnoreCase("META-INF")) continue; if (files[i].equalsIgnoreCase("WEB-INF")) continue; if (deployed.contains(files[i])) continue; File dir = new File(appBase, files[i]); if (dir.isDirectory()) { deployed.add(files[i]); // Make sure there is an application configuration directory // This is needed if the Context appBase is the same as the // web server document root to make sure only web applications // are deployed and not directories for web space. File webInf = new File(dir, "/WEB-INF"); if (!webInf.exists() || !webInf.isDirectory() || !webInf.canRead()) continue; // Calculate the context path and make sure it is unique String contextPath = "/" + files[i]; if (files[i].equals("ROOT")) contextPath = ""; if (host.findChild(contextPath) != null) continue; // Deploy the application in this directory log(sm.getString("hostConfig.deployDir", files[i])); try { URL url = new URL("file", null, dir.getCanonicalPath()); ((Deployer) host).install(contextPath, url); } catch (Throwable t) { log(sm.getString("hostConfig.deployDir.error", files[i]), t); } } } }
protected void start() { // org.apache.catalina.startup.HostConfig.start(). if (debug >= 1) log(sm.getString("hostConfig.start")); if (host.getAutoDeploy()) { deployApps(); } if (isLiveDeploy()) { //highlight line. threadStart(); } }
protected void threadStart() { // org.apache.catalina.startup.HostConfig.threadStart(). // Has the background thread already been started? if (thread != null) return; // Start the background thread if (debug >= 1) log(" Starting background thread"); threadDone = false; threadName = "HostConfig[" + host.getName() + "]"; thread = new Thread(this, threadName); thread.setDaemon(true); thread.start(); } public void run() { //org.apache.catalina.startup.HostConfig.run(). if (debug >= 1) log("BACKGROUND THREAD Starting"); // Loop until the termination semaphore is set while (!threadDone) { // Wait for our check interval threadSleep(); // Deploy apps if the Host allows auto deploying deployApps(); // Check for web.xml modification checkWebXmlLastModified(); } if (debug >= 1) log("BACKGROUND THREAD Stopping"); }
protected void threadSleep() { try { Thread.sleep(checkInterval * 1000L); } // ...... }5)在tomcat5中,HostConfig 类没有再使用专用线程来执行检查工作,而是由StandardHost.backgroundProcess()方法周期性地触发一个 "check"事件;
public void backgroundProcess() { lifecycle.fireLifecycleEvent("check", null); }
public void lifecycleEvent(LifecycleEvent event) { //org.apache.catalina.startup.HostConfig.lifecycleEvent(). if (event.getType().equals(Lifecycle.PERIODIC_EVENT)) check(); // highlight line. // Identify the host we are associated with try { host = (Host) event.getLifecycle(); if (host instanceof StandardHost) { setDeployXML(((StandardHost) host).isDeployXML()); setUnpackWARs(((StandardHost) host).isUnpackWARs()); setXmlNamespaceAware(((StandardHost) host).getXmlNamespaceAware()); setXmlValidation(((StandardHost) host).getXmlValidation()); } } catch (ClassCastException e) { log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e); return; } // Process the event that has occurred if (event.getType().equals(Lifecycle.START_EVENT)) start(); else if (event.getType().equals(Lifecycle.STOP_EVENT)) stop(); }
protected void check() { //org.apache.catalina.startup.HostConfig.check(). if (host.getAutoDeploy()) { // Check for resources modification to trigger redeployment DeployedApplication[] apps = (DeployedApplication[]) deployed.values().toArray(new DeployedApplication[0]); for (int i = 0; i < apps.length; i++) { if (!isServiced(apps[i].name)) checkResources(apps[i]); } // Hotdeploy applications deployApps(); // ...... checkContextLastModified(); } }
A1)check方法会调用 deployApps()方法,该方法都会完成web 应用程序的部署工作,该方法会调用 deployDescriptors方法,deployWARs方法,deployDirectories方法;protected void deployApps() { //org.apache.catalina.startup.HostConfig.deployApps(). if (!(host instanceof Deployer)) return; if (debug >= 1) log(sm.getString("hostConfig.deploying")); File appBase = appBase(); if (!appBase.exists() || !appBase.isDirectory()) return; String files[] = appBase.list(); deployDescriptors(appBase, files); deployWARs(appBase, files); deployDirectories(appBase, files); }A2)check()方法还会调用checkContextLastModified方法,后者遍历所有已经部署的Context,检查web.xml 文件的 时间戳,以及每个Context中 WEB-INF 目录下的内容;如果某个检查的资源被修改了,会重新启动相应的Context实例。此外,该方法还会检查所有已经部署的WAR文件的时间戳,如果某个应用程序的WAR 文件被修改了,会重新对该应用程序进行部署;
public class StandardHost extends ContainerBase implements Deployer, Host { //......
public interface Deployer { //org.apache.catalina.Deployer. public static final String PRE_INSTALL_EVENT = "pre-install"; public static final String INSTALL_EVENT = "install"; public static final String REMOVE_EVENT = "remove"; public String getName(); public void install(String contextPath, URL war) throws IOException; public void install(URL config, URL war) throws IOException; public Context findDeployedApp(String contextPath); public String[] findDeployedApps(); public void remove(String contextPath) throws IOException; public void remove(String contextPath, boolean undeploy) throws IOException; public void start(String contextPath) throws IOException; public void stop(String contextPath) throws IOException; }
// the follwing code is defined in org.apache.catalina.core.StandardHost public void install(String contextPath, URL war) throws IOException { deployer.install(contextPath, war); } public synchronized void install(URL config, URL war) throws IOException { deployer.install(config, war); } public Context findDeployedApp(String contextPath) { return (deployer.findDeployedApp(contextPath)); } public String[] findDeployedApps() { return (deployer.findDeployedApps()); } public void remove(String contextPath) throws IOException { deployer.remove(contextPath); } public void remove(String contextPath, boolean undeploy) throws IOException { deployer.remove(contextPath,undeploy); } public void start(String contextPath) throws IOException { deployer.start(contextPath); } public void stop(String contextPath) throws IOException { deployer.stop(contextPath); } protected void addDefaultMapper(String mapperClass) { super.addDefaultMapper(this.mapperClass); }
public StandardHostDeployer(StandardHost host) { super(); this.host = host; }
protected void deployDescriptors(File appBase, String[] files) { // org.apache.catalina.startup.HostConfig.deployDescriptors() if (!deployXML) return; for (int i = 0; i < files.length; i++) { if (files[i].equalsIgnoreCase("META-INF")) continue; if (files[i].equalsIgnoreCase("WEB-INF")) continue; if (deployed.contains(files[i])) continue; File dir = new File(appBase, files[i]); if (files[i].toLowerCase().endsWith(".xml")) { deployed.add(files[i]); // Calculate the context path and make sure it is unique String file = files[i].substring(0, files[i].length() - 4); String contextPath = "/" + file; if (file.equals("ROOT")) { contextPath = ""; } if (host.findChild(contextPath) != null) { continue; } // Assume this is a configuration descriptor and deploy it log(sm.getString("hostConfig.deployDescriptor", files[i])); try { URL config = new URL("file", null, dir.getCanonicalPath()); ((Deployer) host).install(config, null); // highlight line. } catch (Throwable t) { log(sm.getString("hostConfig.deployDescriptor.error", files[i]), t); } } } }
public synchronized void install(URL config, URL war) throws IOException { // org.apache.catalina.core.StandardHost.install(). deployer.install(config, war); // highlight line. }
public synchronized void install(URL config, URL war) throws IOException { // org.apache.catalina.core.StandardHostDeployer.install(). // Validate the format and state of our arguments if (config == null) throw new IllegalArgumentException (sm.getString("standardHost.configRequired")); if (!host.isDeployXML()) throw new IllegalArgumentException (sm.getString("standardHost.configNotAllowed")); // Calculate the document base for the new web application (if needed) String docBase = null; // Optional override for value in config file if (war != null) { String url = war.toString(); host.log(sm.getString("standardHost.installingWAR", url)); // Calculate the WAR file absolute pathname if (url.startsWith("jar:")) { url = url.substring(4, url.length() - 2); } if (url.startsWith("file://")) docBase = url.substring(7); else if (url.startsWith("file:")) docBase = url.substring(5); else throw new IllegalArgumentException (sm.getString("standardHost.warURL", url)); } // Install the new web application this.context = null; this.overrideDocBase = docBase; InputStream stream = null; try { stream = config.openStream(); Digester digester = createDigester(); digester.setDebug(host.getDebug()); digester.clear(); digester.push(this); digester.parse(stream); stream.close(); stream = null; } catch (Exception e) { host.log (sm.getString("standardHost.installError", docBase), e); throw new IOException(e.toString()); } finally { if (stream != null) { try { stream.close(); } catch (Throwable t) { ; } } } }
public synchronized void install(URL config, URL war) throws IOException { // org.apache.catalina.core.StandardHost.install(). deployer.install(config, war); // highlight line. } public synchronized void install(URL config, URL war) throws IOException { // org.apache.catalina.core.StandardHostDeployer.install(). // Validate the format and state of our arguments if (config == null) throw new IllegalArgumentException (sm.getString("standardHost.configRequired")); if (!host.isDeployXML()) throw new IllegalArgumentException (sm.getString("standardHost.configNotAllowed")); // Calculate the document base for the new web application (if needed) String docBase = null; // Optional override for value in config file if (war != null) { String url = war.toString(); host.log(sm.getString("standardHost.installingWAR", url)); // Calculate the WAR file absolute pathname if (url.startsWith("jar:")) { url = url.substring(4, url.length() - 2); } if (url.startsWith("file://")) docBase = url.substring(7); else if (url.startsWith("file:")) docBase = url.substring(5); else throw new IllegalArgumentException (sm.getString("standardHost.warURL", url)); } // Install the new web application this.context = null; this.overrideDocBase = docBase; InputStream stream = null; try { stream = config.openStream(); Digester digester = createDigester(); digester.setDebug(host.getDebug()); digester.clear(); digester.push(this); digester.parse(stream); stream.close(); stream = null; } catch (Exception e) { host.log (sm.getString("standardHost.installError", docBase), e); throw new IOException(e.toString()); } finally { if (stream != null) { try { stream.close(); } catch (Throwable t) { ; } } } } public synchronized void install(String contextPath, URL war) throws IOException { // Validate the format and state of our arguments if (contextPath == null) throw new IllegalArgumentException (sm.getString("standardHost.pathRequired")); if (!contextPath.equals("") && !contextPath.startsWith("/")) throw new IllegalArgumentException (sm.getString("standardHost.pathFormat", contextPath)); if (findDeployedApp(contextPath) != null) throw new IllegalStateException (sm.getString("standardHost.pathUsed", contextPath)); if (war == null) throw new IllegalArgumentException (sm.getString("standardHost.warRequired")); // Calculate the document base for the new web application host.log(sm.getString("standardHost.installing", contextPath, war.toString())); String url = war.toString(); String docBase = null; boolean isWAR = false; if (url.startsWith("jar:")) { url = url.substring(4, url.length() - 2); if (!url.toLowerCase().endsWith(".war")) { throw new IllegalArgumentException (sm.getString("standardHost.warURL", url)); } isWAR = true; } if (url.startsWith("file://")) docBase = url.substring(7); else if (url.startsWith("file:")) docBase = url.substring(5); else throw new IllegalArgumentException (sm.getString("standardHost.warURL", url)); // Determine if directory/war to install is in the host appBase boolean isAppBase = false; File appBase = new File(host.getAppBase()); if (!appBase.isAbsolute()) appBase = new File(System.getProperty("catalina.base"), host.getAppBase()); File contextFile = new File(docBase); File baseDir = contextFile.getParentFile(); if (appBase.getCanonicalPath().equals(baseDir.getCanonicalPath())) { isAppBase = true; } // For security, if deployXML is false only allow directories // and war files from the hosts appBase if (!host.isDeployXML() && !isAppBase) { throw new IllegalArgumentException (sm.getString("standardHost.installBase", url)); } // Make sure contextPath and directory/war names match when // installing from the host appBase if (isAppBase && (host.getAutoDeploy() || host.getLiveDeploy())) { String filename = contextFile.getName(); if (isWAR) { filename = filename.substring(0,filename.length()-4); } if (contextPath.length() == 0) { if (!filename.equals("ROOT")) { throw new IllegalArgumentException (sm.getString("standardHost.pathMatch", "/", "ROOT")); } } else if (!filename.equals(contextPath.substring(1))) { throw new IllegalArgumentException (sm.getString("standardHost.pathMatch", contextPath, filename)); } } // Expand war file if host wants wars unpacked if (isWAR && host.isUnpackWARs()) { if (contextPath.equals("")) { docBase = ExpandWar.expand(host,war,"/ROOT"); } else { docBase = ExpandWar.expand(host,war,contextPath); } } // Install the new web application try { Class clazz = Class.forName(host.getContextClass()); Context context = (Context) clazz.newInstance(); context.setPath(contextPath); context.setDocBase(docBase); if (context instanceof Lifecycle) { clazz = Class.forName(host.getConfigClass()); LifecycleListener listener = (LifecycleListener) clazz.newInstance(); ((Lifecycle) context).addLifecycleListener(listener); } host.fireContainerEvent(PRE_INSTALL_EVENT, context); host.addChild(context); host.fireContainerEvent(INSTALL_EVENT, context); } catch (Exception e) { host.log(sm.getString("standardHost.installError", contextPath), e); throw new IOException(e.toString()); } }
public void start(String contextPath) throws IOException { // Validate the format and state of our arguments if (contextPath == null) throw new IllegalArgumentException (sm.getString("standardHost.pathRequired")); if (!contextPath.equals("") && !contextPath.startsWith("/")) throw new IllegalArgumentException (sm.getString("standardHost.pathFormat", contextPath)); Context context = findDeployedApp(contextPath); if (context == null) throw new IllegalArgumentException (sm.getString("standardHost.pathMissing", contextPath)); host.log("standardHost.start " + contextPath); try { ((Lifecycle) context).start(); } catch (LifecycleException e) { host.log("standardHost.start " + contextPath + ": ", e); throw new IllegalStateException ("standardHost.start " + contextPath + ": " + e); } }
public void stop(String contextPath) throws IOException { // Validate the format and state of our arguments if (contextPath == null) throw new IllegalArgumentException (sm.getString("standardHost.pathRequired")); if (!contextPath.equals("") && !contextPath.startsWith("/")) throw new IllegalArgumentException (sm.getString("standardHost.pathFormat", contextPath)); Context context = findDeployedApp(contextPath); if (context == null) throw new IllegalArgumentException (sm.getString("standardHost.pathMissing", contextPath)); host.log("standardHost.stop " + contextPath); try { ((Lifecycle) context).stop(); } catch (LifecycleException e) { host.log("standardHost.stop " + contextPath + ": ", e); throw new IllegalStateException ("standardHost.stop " + contextPath + ": " + e); } }
C1)部署器:是用来部署和安装web 应用程序的组件,是org.apache.catalina.Deployer接口的实例;C2)StandardHost:是Deployer接口的一个实例,使其成为一个 可以向其中部署web 应用程序的特殊容器;C3)StandardHost类会将部署和安装web 应用程序的任务委托给其辅助类 org.apache.catalina.core.StandardHostDeployer类完成。C4)StandardHostDeployer类:提供了部署和安装web 应用程序以及启动/ 关闭 Context实例的代码;
标签:
原文地址:http://blog.csdn.net/pacosonswjtu/article/details/51547778