예제 #1
0
  @BeforeClass(alwaysRun = true)
  public void setUpGlobal() throws Exception {

    port1 = findFreePort();
    embedded = new Embedded();
    String path = new File(".").getAbsolutePath();
    embedded.setCatalinaHome(path);

    Engine engine = embedded.createEngine();
    engine.setDefaultHost("127.0.0.1");

    Host host = embedded.createHost("127.0.0.1", path);
    engine.addChild(host);

    Context c = embedded.createContext("/", path);
    c.setReloadable(false);
    Wrapper w = c.createWrapper();
    w.addMapping("/*");
    w.setServletClass(org.apache.catalina.servlets.WebdavServlet.class.getName());
    w.addInitParameter("readonly", "false");
    w.addInitParameter("listings", "true");

    w.setLoadOnStartup(0);

    c.addChild(w);
    host.addChild(c);

    Connector connector =
        embedded.createConnector("127.0.0.1", port1, Http11NioProtocol.class.getName());
    connector.setContainer(host);
    embedded.addEngine(engine);
    embedded.addConnector(connector);
    embedded.start();
  }
  private void initServer() throws Exception {
    // point catalina at the provided home directory
    server = new Embedded();
    server.setCatalinaHome(catalinaHome.getAbsolutePath());

    Engine engine = server.createEngine();
    engine.setName("embedded");
    server.addEngine(engine);

    host = server.createHost("localhost", new File(catalinaHome, "webapps").getAbsolutePath());
    engine.addChild(host);
    engine.setDefaultHost(host.getName());

    // bind to an available port
    httpConnector = new EmbeddedConnector();
    server.addConnector(httpConnector);

    // disable session persistence on restart
    sessions = new MemoryStore();
    sessionManager = new PersistentManager();
    sessionManager.setDistributable(false);
    sessionManager.setSaveOnRestart(false);
    sessionManager.setStore(sessions);

    Context root = server.createContext("", new File(catalinaHome, "conf").getAbsolutePath());
    root.setManager(sessionManager);
    host.addChild(root);
  }
예제 #3
0
  private static StandardContext startWebApp(Host host, WSEndpointDeploymentUnit unit)
      throws Exception {
    StandardContext context = new StandardContext();
    try {
      JBossWebMetaData jbwebMD = unit.getAttachment(WSAttachmentKeys.JBOSSWEB_METADATA_KEY);
      context.setPath(jbwebMD.getContextRoot());
      context.addLifecycleListener(new ContextConfig());
      ServerConfigService config =
          (ServerConfigService)
              unit.getServiceRegistry().getService(WSServices.CONFIG_SERVICE).getService();
      File docBase = new File(config.getValue().getServerTempDir(), jbwebMD.getContextRoot());
      if (!docBase.exists()) {
        docBase.mkdirs();
      }
      context.setDocBase(docBase.getPath());

      final Loader loader = new WebCtxLoader(unit.getAttachment(WSAttachmentKeys.CLASSLOADER_KEY));
      loader.setContainer(host);
      context.setLoader(loader);
      context.setInstanceManager(new LocalInstanceManager());

      addServlets(jbwebMD, context);

      host.addChild(context);
      context.create();
    } catch (Exception e) {
      throw MESSAGES.createContextPhaseFailed(e);
    }
    try {
      context.start();
    } catch (LifecycleException e) {
      throw MESSAGES.startContextPhaseFailed(e);
    }
    return context;
  }
 protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
   File docBase = getValidDocumentRoot();
   docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase"));
   TomcatEmbeddedContext context = new TomcatEmbeddedContext();
   context.setName(getContextPath());
   context.setPath(getContextPath());
   context.setDocBase(docBase.getAbsolutePath());
   context.addLifecycleListener(new FixContextListener());
   context.setParentClassLoader(
       this.resourceLoader != null
           ? this.resourceLoader.getClassLoader()
           : ClassUtils.getDefaultClassLoader());
   SkipPatternJarScanner.apply(context, this.tldSkip);
   WebappLoader loader = new WebappLoader(context.getParentClassLoader());
   loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
   loader.setDelegate(true);
   context.setLoader(loader);
   if (isRegisterDefaultServlet()) {
     addDefaultServlet(context);
   }
   if (isRegisterJspServlet()
       && ClassUtils.isPresent(getJspServletClassName(), getClass().getClassLoader())) {
     addJspServlet(context);
     addJasperInitializer(context);
     context.addLifecycleListener(new StoreMergedWebXmlListener());
   }
   ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
   configureContext(context, initializersToUse);
   host.addChild(context);
   postProcessContext(context);
 }
  /**
   * Creates a single webapp configuration to be run in Tomcat.
   *
   * @param contextName the context name without leading slash, for example, "openmrs"
   * @param port the port at which to run tomcat.
   */
  public TomcatManager(String contextName, int port) {

    // create server
    container = new Embedded();
    container.setCatalinaHome("tomcat");

    // create context
    Context rootContext = container.createContext("/" + contextName, contextName);
    rootContext.setReloadable(true);

    // create host
    Host localHost = container.createHost("localhost", "webapps");
    localHost.addChild(rootContext);

    // create engine
    Engine engine = container.createEngine();
    engine.setName("Catalina");
    engine.addChild(localHost);
    engine.setDefaultHost(localHost.getName());
    container.addEngine(engine);

    // create http connector
    Connector httpConnector = container.createConnector((InetAddress) null, port, false);
    container.addConnector(httpConnector);
  }
예제 #6
0
  @Override
  public void start(StartContext startContext) throws StartException {

    ServerEnvironment env = injectedServerEnvironment.getValue();
    Host virtualHost = injectedVirtualHost.getValue().getHost();
    BundleContext syscontext = injectedSystemContext.getValue();
    WebServer webServer = injectedWebServer.getValue();

    File storageDir =
        new File(
            env.getServerTempDir()
                + File.separator
                + CONTEXT_NAME
                + File.separator
                + "httpservice-root");
    context.setDocBase(storageDir.getPath());
    storageDir.mkdirs();

    context.setPath(CONTEXT_NAME);
    context.addLifecycleListener(new ContextConfig());
    Loader loader = new WebCtxLoader(getClass().getClassLoader());
    loader.setContainer(virtualHost);
    context.setLoader(loader);
    context.setInstanceManager(new LocalInstanceManager());

    context.addMimeMapping("html", "text/html");
    context.addMimeMapping("jpg", "image/jpeg");
    context.addMimeMapping("png", "image/png");
    context.addMimeMapping("gif", "image/gif");
    context.addMimeMapping("css", "text/css");
    context.addMimeMapping("js", "text/javascript");

    virtualHost.addChild(context);

    WEB_LOGGER.registerWebapp(context.getName());
    try {
      context.create();
    } catch (Exception ex) {
      throw new StartException(WebMessages.MESSAGES.createContextFailed(), ex);
    }
    try {
      context.start();
    } catch (LifecycleException ex) {
      throw new StartException(WebMessages.MESSAGES.startContextFailed(), ex);
    }

    Hashtable<String, Object> props = new Hashtable<String, Object>();
    props.put(Constants.SERVICE_RANKING, Integer.MIN_VALUE);
    props.put("provider", getClass().getPackage().getName());

    ServiceFactory serviceFactory = new HttpServiceFactory(webServer, virtualHost, context);
    registration = syscontext.registerService(HttpService.class.getName(), serviceFactory, props);
  }
예제 #7
0
 public static void setupContainer(String warName, String jvmRoute, Manager mgr) {
   Engine engine = new MockEngine();
   engine.setName(JVM_ROUTE_CACHE_NAME);
   engine.setJvmRoute(jvmRoute);
   Host host = new MockHost();
   host.setName("localhost");
   engine.addChild(host);
   StandardContext context = new StandardContext();
   context.setName(warName);
   context.setDomain(jvmRoute);
   host.addChild(context);
   context.setManager(mgr);
 }
예제 #8
0
  public Context addContext(Host host, String contextPath, String contextName, String dir) {
    silence(host, contextPath);
    Context ctx = new StandardContext();
    ctx.setName(contextName);
    ctx.setPath(contextPath);
    ctx.setDocBase(dir);
    ctx.addLifecycleListener(new FixContextListener());

    if (host == null) {
      getHost().addChild(ctx);
    } else {
      host.addChild(ctx);
    }
    return ctx;
  }
예제 #9
0
  /**
   * Add a new Context to be managed by us. Entry point for the admin webapp, and other JMX Context
   * controlers.
   */
  public void manageApp(Context context) {

    String contextPath = context.getPath();

    if (deployed.containsKey(contextPath)) return;

    DeployedApplication deployedApp = new DeployedApplication(contextPath);

    // Add the associated docBase to the redeployed list if it's a WAR
    boolean isWar = false;
    if (context.getDocBase() != null) {
      File docBase = new File(context.getDocBase());
      if (!docBase.isAbsolute()) {
        docBase = new File(appBase(), context.getDocBase());
      }
      deployedApp.redeployResources.put(
          docBase.getAbsolutePath(), new Long(docBase.lastModified()));
      if (docBase.getAbsolutePath().toLowerCase().endsWith(".war")) {
        isWar = true;
      }
    }
    host.addChild(context);
    // Add the eventual unpacked WAR and all the resources which will be
    // watched inside it
    if (isWar && unpackWARs) {
      String name = null;
      String path = context.getPath();
      if (path.equals("")) {
        name = "ROOT";
      } else {
        if (path.startsWith("/")) {
          name = path.substring(1);
        } else {
          name = path;
        }
      }
      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);
    }
    deployed.put(contextPath, deployedApp);
  }
예제 #10
0
  public EmbeddedTomcat(String contextPath, int port, String jvmRoute)
      throws MalformedURLException {
    this.contextPath = contextPath;
    this.port = port;

    // create server
    container = new Embedded();
    container.setCatalinaHome(catalinaHome);
    // Not really necessasry, but let's still do it...
    container.setRealm(new MemoryRealm());

    // create webapp loader
    WebappLoader loader = new WebappLoader(this.getClass().getClassLoader());
    if (classesDir != null) {
      loader.addRepository(new File(classesDir).toURI().toURL().toString());
    }

    rootContext = container.createContext("", webappDir);
    rootContext.setLoader(loader);
    rootContext.setReloadable(true);
    // Otherwise we get NPE when instantiating servlets
    rootContext.setIgnoreAnnotations(true);

    // create host
    Host localHost = container.createHost("127.0.0.1", new File("").getAbsolutePath());
    localHost.addChild(rootContext);

    localHost.setDeployOnStartup(true);

    // create engine
    engine = container.createEngine();
    engine.setName("localEngine");
    engine.addChild(localHost);
    engine.setDefaultHost(localHost.getName());
    engine.setJvmRoute(jvmRoute);
    engine.setService(new StandardService());
    container.addEngine(engine);

    // create http connector
    Connector httpConnector = container.createConnector((InetAddress) null, port, false);
    container.addConnector(httpConnector);
    container.setAwait(true);

    // Create the JVMRoute valve for session failover
    ValveBase valve = new JvmRouteBinderValve();
    ((StandardEngine) engine).addValve(valve);
  }
  @Override
  public synchronized void start() throws Exception {

    Host host = ServerUtil.getDefaultHost().getHost();
    _serverContext = (StandardContext) host.findChild("/" + _contextName);
    if (_serverContext == null) {
      _serverContext = new StandardContext();
      _serverContext.setPath("/" + _contextName);
      File docBase = new File(SERVER_TEMP_DIR, _contextName);
      if (!docBase.exists()) {
        if (!docBase.mkdirs()) {
          throw new RuntimeException("Unable to create temp directory " + docBase.getPath());
        }
      }
      _serverContext.setDocBase(docBase.getPath());
      _serverContext.addLifecycleListener(new ContextConfig());

      final Loader loader = new WebCtxLoader(Thread.currentThread().getContextClassLoader());
      loader.setContainer(host);
      _serverContext.setLoader(loader);
      _serverContext.setInstanceManager(new LocalInstanceManager());

      Wrapper wrapper = _serverContext.createWrapper();
      wrapper.setName(SERVLET_NAME);
      wrapper.setServletClass(SwitchYardRemotingServlet.class.getName());
      wrapper.setLoadOnStartup(1);
      _serverContext.addChild(wrapper);
      _serverContext.addServletMapping("/*", SERVLET_NAME);

      host.addChild(_serverContext);
      _serverContext.create();
      _serverContext.start();

      SwitchYardRemotingServlet remotingServlet = (SwitchYardRemotingServlet) wrapper.getServlet();
      remotingServlet.setEndpointPublisher(this);
      _log.info("Published Remote Service Endpoint " + _serverContext.getPath());
    } else {
      throw new RuntimeException("Context " + _contextName + " already exists!");
    }
  }
예제 #12
0
 protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
   File docBase = getValidDocumentRoot();
   docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase"));
   TomcatEmbeddedContext context = new TomcatEmbeddedContext();
   context.setName(getContextPath());
   context.setDisplayName(getDisplayName());
   context.setPath(getContextPath());
   context.setDocBase(docBase.getAbsolutePath());
   context.addLifecycleListener(new FixContextListener());
   context.setParentClassLoader(
       this.resourceLoader != null
           ? this.resourceLoader.getClassLoader()
           : ClassUtils.getDefaultClassLoader());
   try {
     context.setUseRelativeRedirects(false);
     context.setMapperContextRootRedirectEnabled(true);
   } catch (NoSuchMethodError ex) {
     // Tomcat is < 8.0.30. Continue
   }
   SkipPatternJarScanner.apply(context, this.tldSkip);
   WebappLoader loader = new WebappLoader(context.getParentClassLoader());
   loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
   loader.setDelegate(true);
   context.setLoader(loader);
   if (isRegisterDefaultServlet()) {
     addDefaultServlet(context);
   }
   if (shouldRegisterJspServlet()) {
     addJspServlet(context);
     addJasperInitializer(context);
     context.addLifecycleListener(new StoreMergedWebXmlListener());
   }
   ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
   configureContext(context, initializersToUse);
   host.addChild(context);
   postProcessContext(context);
 }
예제 #13
0
  public Context addWebapp(Host host, String url, String name, String path) {
    silence(host, url);

    Context ctx = new StandardContext();
    ctx.setName(name);
    ctx.setPath(url);
    ctx.setDocBase(path);

    ctx.addLifecycleListener(new DefaultWebXmlListener());

    ContextConfig ctxCfg = new ContextConfig();
    ctx.addLifecycleListener(ctxCfg);

    // prevent it from looking ( if it finds one - it'll have dup error )
    ctxCfg.setDefaultWebXml(noDefaultWebXmlPath());

    if (host == null) {
      getHost().addChild(ctx);
    } else {
      host.addChild(ctx);
    }

    return ctx;
  }
예제 #14
0
  /**
   * @param contextPath
   * @param war
   * @param file
   */
  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);
  }
예제 #15
0
  /**
   * @param contextPath
   * @param dir
   * @param file
   */
  protected void deployDirectory(String contextPath, File dir, String file) {
    DeployedApplication deployedApp = new DeployedApplication(contextPath);

    if (deploymentExists(contextPath)) return;

    // Deploy the application in this directory
    if (log.isInfoEnabled()) log.info(sm.getString("hostConfig.deployDir", file));
    try {
      Context context = null;
      File xml = new File(dir, Constants.ApplicationContextXml);
      File xmlCopy = null;
      if (deployXML && xml.exists()) {
        // Will only do this on initial deployment. On subsequent
        // deployments the copied xml file means we'll use
        // deployDescriptor() instead
        synchronized (digester) {
          try {
            context = (Context) digester.parse(xml);
            if (context == null) {
              log.error(sm.getString("hostConfig.deployDescriptor.error", xml));
              return;
            }
          } finally {
            digester.reset();
          }
        }
        configBase.mkdirs();
        xmlCopy = new File(configBase, file + ".xml");
        InputStream is = null;
        OutputStream os = null;
        try {
          is = new FileInputStream(xml);
          os = new FileOutputStream(xmlCopy);
          IOTools.flow(is, os);
          // Don't catch IOE - let the outer try/catch handle it
        } finally {
          try {
            if (is != null) is.close();
          } catch (IOException e) {
            // Ignore
          }
          try {
            if (os != null) os.close();
          } catch (IOException e) {
            // Ignore
          }
        }
        context.setConfigFile(xmlCopy.getAbsolutePath());
      } else {
        context = (Context) Class.forName(contextClass).newInstance();
      }

      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);
      deployedApp.redeployResources.put(dir.getAbsolutePath(), new Long(dir.lastModified()));
      if (xmlCopy != null) {
        deployedApp.redeployResources.put(
            xmlCopy.getAbsolutePath(), new Long(xmlCopy.lastModified()));
      }
      addWatchedResources(deployedApp, dir.getAbsolutePath(), context);
    } catch (Throwable t) {
      log.error(sm.getString("hostConfig.deployDir.error", file), t);
    }

    deployed.put(contextPath, deployedApp);
  }
예제 #16
0
  public static void main(String[] args) {

    System.setProperty("catalina.base", System.getProperty("user.dir"));
    Connector connector = new HttpConnector();

    Wrapper wrapper1 = new StandardWrapper();
    wrapper1.setName("Primitive");
    wrapper1.setServletClass("PrimitiveServlet");
    Wrapper wrapper2 = new StandardWrapper();
    wrapper2.setName("Modern");
    wrapper2.setServletClass("ModernServlet");

    Context context = new StandardContext();
    // StandardContext's start method adds a default mapper
    context.setPath("/app1");
    context.setDocBase("app1");

    context.addChild(wrapper1);
    context.addChild(wrapper2);

    LifecycleListener listener = new SimpleContextConfig();
    ((Lifecycle) context).addLifecycleListener(listener);

    Host host = new StandardHost();
    host.addChild(context);
    host.setName("localhost");
    host.setAppBase("webapps");

    Loader loader = new WebappLoader();
    context.setLoader(loader);
    // context.addServletMapping(pattern, name);
    context.addServletMapping("/Primitive", "Primitive");
    context.addServletMapping("/Modern", "Modern");

    Engine engine = new StandardEngine();
    engine.addChild(host);
    engine.setDefaultHost("localhost");

    Service service = new StandardService();
    service.setName("Stand-alone Service");
    Server server = new StandardServer();
    server.addService(service);
    service.addConnector(connector);

    // StandardService class's setContainer will call all its connector's setContainer method
    service.setContainer(engine);

    // Start the new server
    if (server instanceof Lifecycle) {
      try {
        server.initialize();
        ((Lifecycle) server).start();
        server.await();
        // the program waits until the await method returns,
        // i.e. until a shutdown command is received.
      } catch (LifecycleException e) {
        e.printStackTrace(System.out);
      }
    }

    // Shut down the server
    if (server instanceof Lifecycle) {
      try {
        ((Lifecycle) server).stop();
      } catch (LifecycleException e) {
        e.printStackTrace(System.out);
      }
    }
  }
 public void deployDescriptor(String contextRoot, File descriptorFile) {
   Context context = newContext(contextRoot, descriptorFile.getParentFile());
   context.setAltDDName(descriptorFile.getAbsolutePath());
   host.addChild(context);
 }
 public void deployExploded(File explodedDir) {
   Context context = newContext("/" + explodedDir.getName(), explodedDir);
   host.addChild(context);
 }
예제 #19
0
  /**
   * @param contextPath
   * @param contextXml
   * @param file
   */
  protected void deployDescriptor(String contextPath, File contextXml, String file) {
    if (deploymentExists(contextPath)) {
      return;
    }

    DeployedApplication deployedApp = new DeployedApplication(contextPath);

    // Assume this is a configuration descriptor and deploy it
    if (log.isInfoEnabled()) {
      log.info(sm.getString("hostConfig.deployDescriptor", file));
    }

    Context context = null;
    try {
      synchronized (digester) {
        try {
          context = (Context) digester.parse(contextXml);
          if (context == null) {
            log.error(sm.getString("hostConfig.deployDescriptor.error", file));
            return;
          }
        } finally {
          digester.reset();
        }
      }
      if (context instanceof Lifecycle) {
        Class clazz = Class.forName(host.getConfigClass());
        LifecycleListener listener = (LifecycleListener) clazz.newInstance();
        ((Lifecycle) context).addLifecycleListener(listener);
      }
      context.setConfigFile(contextXml.getAbsolutePath());
      context.setPath(contextPath);
      // Add the associated docBase to the redeployed list if it's a WAR
      boolean isExternalWar = false;
      boolean isExternal = false;
      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(), new Long(contextXml.lastModified()));
          deployedApp.redeployResources.put(
              docBase.getAbsolutePath(), new Long(docBase.lastModified()));
          if (docBase.getAbsolutePath().toLowerCase().endsWith(".war")) {
            isExternalWar = true;
          }
        } else {
          log.warn(sm.getString("hostConfig.deployDescriptor.localDocBaseSpecified", docBase));
          // Ignore specified docBase
          context.setDocBase(null);
        }
      }
      host.addChild(context);
      // Get paths for WAR and expanded WAR in appBase
      String name = null;
      String path = context.getPath();
      if (path.equals("")) {
        name = "ROOT";
      } else {
        if (path.startsWith("/")) {
          name = path.substring(1);
        } else {
          name = path;
        }
      }
      File expandedDocBase = new File(appBase(), name);
      if (context.getDocBase() != null) {
        // 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());
        }
      }
      // Add the eventual unpacked WAR and all the resources which will be
      // watched inside it
      if (isExternalWar && unpackWARs) {
        deployedApp.redeployResources.put(
            expandedDocBase.getAbsolutePath(), new Long(expandedDocBase.lastModified()));
        deployedApp.redeployResources.put(
            contextXml.getAbsolutePath(), new Long(contextXml.lastModified()));
        addWatchedResources(deployedApp, expandedDocBase.getAbsolutePath(), 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(), new Long(warDocBase.lastModified()));
          }
        }
        if (expandedDocBase.exists()) {
          deployedApp.redeployResources.put(
              expandedDocBase.getAbsolutePath(), new Long(expandedDocBase.lastModified()));
          addWatchedResources(deployedApp, expandedDocBase.getAbsolutePath(), context);
        } else {
          addWatchedResources(deployedApp, null, context);
        }
        // Add the context XML to the list of files which should trigger a redeployment
        if (!isExternal) {
          deployedApp.redeployResources.put(
              contextXml.getAbsolutePath(), new Long(contextXml.lastModified()));
        }
      }
    } catch (Throwable t) {
      log.error(sm.getString("hostConfig.deployDescriptor.error", file), t);
    }

    if (context != null && host.findChild(context.getName()) != null) {
      deployed.put(contextPath, deployedApp);
    }
  }