tomcat原始碼淺析(三)之webapps的解析
阿新 • • 發佈:2019-01-05
1.HostConfig在start中會呼叫deployApps方法掃描appBase目錄下的apps,載入DocBase/META-INF/context.xml.
Hostconfig.deployapps程式碼- protected void deployApps() {
- File appBase = appBase();
- File configBase = configBase();
- String[] filteredAppPaths = filterAppPaths(appBase.list());
- // Deploy XML descriptors from configBase
- deployDescriptors(configBase, configBase.list());
- // Deploy WARs
- deployWARs(appBase, filteredAppPaths);
- // Deploy expanded folders
- deployDirectories(appBase, filteredAppPaths);
- }
Hostconfig.deploydescriptor程式碼
- protected void deployDescriptor(ContextName cn, File contextXml) {
- DeployedApplication deployedApp =
- new DeployedApplication(cn.getName(), true);
- long startTime = 0;
- // Assume this is a configuration descriptor and deploy it
- if(log.isInfoEnabled()) {
- startTime = System.currentTimeMillis();
- log.info(sm.getString("hostConfig.deployDescriptor",
- contextXml.getAbsolutePath()));
- }
- Context context = null;
- boolean isExternalWar = false;
- boolean isExternal = false;
- File expandedDocBase = null;
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(contextXml);
- synchronized (digesterLock) {
- try {
- context = (Context) digester.parse(fis);
- } catch (Exception e) {
- log.error(sm.getString(
- "hostConfig.deployDescriptor.error",
- contextXml.getAbsolutePath()), e);
- context = new FailedContext();
- } finally {
- digester.reset();
- }
- }
- Class<?> clazz = Class.forName(host.getConfigClass());
- LifecycleListener listener =
- (LifecycleListener) clazz.newInstance();
- context.addLifecycleListener(listener);
- context.setConfigFile(contextXml.toURI().toURL());
- context.setName(cn.getName());
- context.setPath(cn.getPath());
- context.setWebappVersion(cn.getVersion());
- // Add the associated docBase to the redeployed list if it's a WAR
- if (context.getDocBase() != null) {
- File docBase = new File(context.getDocBase());
- if (!docBase.isAbsolute()) {
- docBase = new File(appBase(), context.getDocBase());
- }
- // If external docBase, register .xml as redeploy first
- if (!docBase.getCanonicalPath().startsWith(
- appBase().getAbsolutePath() + File.separator)) {
- isExternal = true;
- deployedApp.redeployResources.put(
- contextXml.getAbsolutePath(),
- Long.valueOf(contextXml.lastModified()));
- deployedApp.redeployResources.put(docBase.getAbsolutePath(),
- Long.valueOf(docBase.lastModified()));
- if (docBase.getAbsolutePath().toLowerCase(Locale.ENGLISH).endsWith(".war")) {
- isExternalWar = true;
- }
- } else {
- log.warn(sm.getString("hostConfig.deployDescriptor.localDocBaseSpecified",
- docBase));
- // Ignore specified docBase
- context.setDocBase(null);
- }
- }
- host.addChild(context);
- } catch (Throwable t) {
- ExceptionUtils.handleThrowable(t);
- log.error(sm.getString("hostConfig.deployDescriptor.error",
- contextXml.getAbsolutePath()), t);
- } finally {
- if (fis != null) {
- try {
- fis.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- // Get paths for WAR and expanded WAR in appBase
- // default to appBase dir + name
- expandedDocBase = new File(appBase(), cn.getBaseName());
- if (context.getDocBase() != null
- && !context.getDocBase().toLowerCase(Locale.ENGLISH).endsWith(".war")) {
- // first assume docBase is absolute
- expandedDocBase = new File(context.getDocBase());
- if (!expandedDocBase.isAbsolute()) {
- // if docBase specified and relative, it must be relative to appBase
- expandedDocBase = new File(appBase(), context.getDocBase());
- }
- }
- boolean unpackWAR = unpackWARs;
- if (unpackWAR && context instanceof StandardContext) {
- unpackWAR = ((StandardContext) context).getUnpackWAR();
- }
- // Add the eventual unpacked WAR and all the resources which will be
- // watched inside it
- if (isExternalWar) {
- if (unpackWAR) {
- deployedApp.redeployResources.put(expandedDocBase.getAbsolutePath(),
- Long.valueOf(expandedDocBase.lastModified()));
- addWatchedResources(deployedApp, expandedDocBase.getAbsolutePath(), context);
- } else {
- addWatchedResources(deployedApp, null, context);
- }
- } else {
- // Find an existing matching war and expanded folder
- if (!isExternal) {
- File warDocBase = new File(expandedDocBase.getAbsolutePath() + ".war");
- if (warDocBase.exists()) {
- deployedApp.redeployResources.put(warDocBase.getAbsolutePath(),
- Long.valueOf(warDocBase.lastModified()));
- } else {
- // Trigger a redeploy if a WAR is added
- deployedApp.redeployResources.put(
- warDocBase.getAbsolutePath(),
- Long.valueOf(0));
- }
- }
- if (unpackWAR) {
- deployedApp.redeployResources.put(expandedDocBase.getAbsolutePath(),
- Long.valueOf(expandedDocBase.lastModified()));
- addWatchedResources(deployedApp,
- expandedDocBase.getAbsolutePath(), context);
- } else {
- addWatchedResources(deployedApp, null, context);
- }
- if (!isExternal) {
- // For external docBases, the context.xml will have been
- // added above.
- deployedApp.redeployResources.put(
- contextXml.getAbsolutePath(),
- Long.valueOf(contextXml.lastModified()));
- }
- }
- // Add the global redeploy resources (which are never deleted) at
- // the end so they don't interfere with the deletion process
- addGlobalRedeployResources(deployedApp);
- }
- if (host.findChild(context.getName()) != null) {
- deployed.put(context.getName(), deployedApp);
- }
- if (log.isInfoEnabled()) {
- log.info(sm.getString("hostConfig.deployDescriptor.finished",
- contextXml.getAbsolutePath(), Long.valueOf(System.currentTimeMillis() - startTime)));
- }
- }
Hostconfig.deploywar程式碼
- protected void deployWAR(ContextName cn, File war) {
- // Checking for a nested /META-INF/context.xml
- JarFile jar = null;
- InputStream istream = null;
- FileOutputStream fos = null;
- BufferedOutputStream ostream = null;
- File xml = new File(appBase(),
- cn.getBaseName() + "/META-INF/context.xml");
- boolean xmlInWar = false;
- try {
- jar = new JarFile(war);
- JarEntry entry = jar.getJarEntry(Constants.ApplicationContextXml);
- if (entry != null) {
- xmlInWar = true;
- }
- } catch (IOException e) {
- /* Ignore */
- } finally {
- if (jar != null) {
- try {
- jar.close();
- } catch (IOException ioe) {
- // Ignore;
- }
- jar = null;
- }
- }
- Context context = null;
- try {
- if (deployXML && xml.exists() && unpackWARs && !copyXML) {
- synchronized (digesterLock) {
- try {
- context = (Context) digester.parse(xml);
- } catch (Exception e) {
- log.error(sm.getString(
- "hostConfig.deployDescriptor.error",
- war.getAbsolutePath()), e);
- } finally {
- digester.reset();
- if (context == null) {
- context = new FailedContext();
- }
- }
- }
- context.setConfigFile(xml.toURI().toURL());
- } else if (deployXML && xmlInWar) {
- synchronized (digesterLock) {
- try {
- jar = new JarFile(war);
- JarEntry entry =
- jar.getJarEntry(Constants.ApplicationContextXml);
- istream = jar.getInputStream(entry);
- context = (Context) digester.parse(istream);
- } catch (Exception e) {
- log.error(sm.getString(
- "hostConfig.deployDescriptor.error",
- war.getAbsolutePath()), e);
- } finally {
- digester.reset();
- if (istream != null) {
- try {
- istream.close();
- } catch (IOException e) {
- /* Ignore */
- }
- istream = null;
- }
- if (jar != null) {
- try {
- jar.close();
- } catch (IOException e) {
- /* Ignore */
- }
- jar = null;
- }
- if (context == null) {
- context = new FailedContext();
- }
- context.setConfigFile(
- UriUtil.buildJarUrl(war, Constants.ApplicationContextXml));
- }
- }
- } else if (!deployXML && xmlInWar) {
- // Block deployment as META-INF/context.xml may contain security
- // configuration necessary for a secure deployment.
- log.error(sm.getString("hostConfig.deployDescriptor.blocked",
- cn.getPath(), Constants.ApplicationContextXml,
- new File(configBase(), cn.getBaseName() + ".xml")));
- } else {
- context = (Context) Class.forName(contextClass).newInstance();
- }
- } catch (Throwable t) {
- ExceptionUtils.handleThrowable(t);
- log.error(sm.getString("hostConfig.deployWar.error",
- war.getAbsolutePath()), t);
- } finally {
- if (context == null) {
- context = new FailedContext();
- }
- }
- boolean copyThisXml = false;
- if (deployXML) {
- if (host instanceof StandardHost) {
- copyThisXml = ((StandardHost) host).isCopyXML();
- }
- // If Host is using default value Context can override it.
- if (!copyThisXml && context instanceof StandardContext) {
- copyThisXml = ((StandardContext) context).getCopyXML();
- }
- if (xmlInWar && copyThisXml) {
- // Change location of XML file to config base
- xml = new File(configBase(), cn.getBaseName() + ".xml");
- try {
- jar = new JarFile(war);
- JarEntry entry =
- jar.getJarEntry(Constants.ApplicationContextXml);
- istream = jar.getInputStream(entry);
- fos = new FileOutputStream(xml);
- ostream = new BufferedOutputStream(fos, 1024);
- byte buffer[] = new byte[1024];
- while (true) {
- int n = istream.read(buffer);
- if (n < 0) {
- break;
- }
- ostream.write(buffer, 0, n);
- }
- ostream.flush();
- } catch (IOException e) {
- /* Ignore */
- } finally {
- if (ostream != null) {
- try {
- ostream.close();
- } catch (IOException ioe) {
- // Ignore
- }
- ostream = null;
- }
- if (fos != null) {
- try {
- fos.close();
- } catch (IOException ioe) {
- // Ignore
- }
- fos = null;
- }
- if (istream != null) {
- try {
- istream.close();
- } catch (IOException ioe) {
- // Ignore
- }
- istream = null;
- }
- if (jar != null) {
- try {
- jar.close();
- } catch (IOException ioe) {
- // Ignore;
- }
- jar = null;
- }
- }
- }
- }
- DeployedApplication deployedApp = new DeployedApplication(cn.getName(),
- xml.exists() && deployXML && copyThisXml);
- long startTime = 0;
- // Deploy the application in this WAR file
- if(log.isInfoEnabled()) {
- startTime = System.currentTimeMillis();
- log.info(sm.getString("hostConfig.deployWar",
- war.getAbsolutePath()));
- }
- try {
- // Populate redeploy resources with the WAR file
- deployedApp.redeployResources.put
- (war.getAbsolutePath(), Long.valueOf(war.lastModified()));
- if (deployXML && xml.exists() && copyThisXml) {
- deployedApp.redeployResources.put(xml.getAbsolutePath(),
- Long.valueOf(xml.lastModified()));
- } else {
- // In case an XML file is added to the config base later
- deployedApp.redeployResources.put(
- (new File(configBase(),
- cn.getBaseName() + ".xml")).getAbsolutePath(),
- Long.valueOf(0));
- }
- Class<?> clazz = Class.forName(host.getConfigClass());
- LifecycleListener listener =
- (LifecycleListener) clazz.newInstance();
- context.addLifecycleListener(listener);
- context.setName(cn.getName());
- context.setPath(cn.getPath());
- context.setWebappVersion(cn.getVersion());
- context.setDocBase(cn.getBaseName() + ".war");
- host.addChild(context);
- } catch (Throwable t) {
- ExceptionUtils.handleThrowable(t);
- log.error(sm.getString("hostConfig.deployWar.error",
- war.getAbsolutePath()), t);
- } finally {
- // If we're unpacking WARs, the&nbs