You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by cr...@apache.org on 2002/02/12 23:14:02 UTC

cvs commit: jakarta-tomcat-4.0/webapps/tomcat-docs manager-howto.xml

craigmcc    02/02/12 14:14:02

  Modified:    catalina/src/share/org/apache/catalina/ant
                        AbstractCatalinaTask.java InstallTask.java
                        ListTask.java ReloadTask.java StartTask.java
                        StopTask.java
               catalina/src/share/org/apache/catalina/servlets
                        LocalStrings.properties ManagerServlet.java
               webapps/tomcat-docs manager-howto.xml
  Added:       catalina/src/share/org/apache/catalina/ant DeployTask.java
                        UndeployTask.java
  Log:
  Enhance the Manager webapp to support two new facilities:
  
  * Deploy a new application (optionally to a Tomcat instance running
    on a different server) by uploading the WAR file to it.
  
  * Undeploy an existing application and remove its document base directory
    from webapps.
  
  * Support these commands with new custom Ant tasks, typically named
    <deploy> and <undeploy>.
  
  The first of these commands is useful only within tools, becasue it requires
  an HTTP put.  However, it is supported by an Ant task for use in build
  scripts.
  
  If you want to do application development "in place", inside the context
  root directory of a running webapp, you will probably want to use the
  "install" command rather than the "deploy" command.
  
  Revision  Changes    Path
  1.2       +81 -15    jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/AbstractCatalinaTask.java
  
  Index: AbstractCatalinaTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/AbstractCatalinaTask.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractCatalinaTask.java	11 Jan 2002 00:37:30 -0000	1.1
  +++ AbstractCatalinaTask.java	12 Feb 2002 22:14:01 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/AbstractCatalinaTask.java,v 1.1 2002/01/11 00:37:30 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/01/11 00:37:30 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/AbstractCatalinaTask.java,v 1.2 2002/02/12 22:14:01 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/12 22:14:01 $
    *
    * ====================================================================
    *
  @@ -63,8 +63,10 @@
   package org.apache.catalina.ant;
   
   
  +import java.io.BufferedOutputStream;
   import java.io.InputStream;
   import java.io.InputStreamReader;
  +import java.net.HttpURLConnection;
   import java.net.URL;
   import java.net.URLConnection;
   import org.apache.catalina.util.Base64;
  @@ -79,7 +81,8 @@
    * undeploying applications.  These tasks require Ant 1.4 or later.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2002/01/11 00:37:30 $
  + * @version $Revision: 1.2 $ $Date: 2002/02/12 22:14:01 $
  + * @since 4.1
    */
   
   public abstract class AbstractCatalinaTask extends Task {
  @@ -165,30 +168,84 @@
        */
       public void execute(String command) throws BuildException {
   
  +        execute(command, null, null, -1);
  +
  +    }
  +
  +
  +    /**
  +     * Execute the specified command, based on the configured properties.
  +     * The input stream will be closed upon completion of this task, whether
  +     * it was executed successfully or not.
  +     *
  +     * @param command Command to be executed
  +     * @param istream InputStream to include in an HTTP PUT, if any
  +     * @param contentType Content type to specify for the input, if any
  +     * @param contentLength Content length to specify for the input, if any
  +     *
  +     * @exception BuildException if an error occurs
  +     */
  +    public void execute(String command, InputStream istream,
  +                        String contentType, int contentLength)
  +        throws BuildException {
  +
           URLConnection conn = null;
           InputStreamReader reader = null;
           try {
   
               // Create a connection for this command
               conn = (new URL(url + command)).openConnection();
  +            HttpURLConnection hconn = (HttpURLConnection) conn;
   
               // Set up standard connection characteristics
  -            conn.setAllowUserInteraction(false);
  -            conn.setDoInput(true);
  -            conn.setDoOutput(false);
  -            conn.setUseCaches(false);
  -            conn.setRequestProperty("User-Agent",
  -                                    "Catalina-Ant-Task/1.0");
  +            hconn.setAllowUserInteraction(false);
  +            hconn.setDoInput(true);
  +            hconn.setUseCaches(false);
  +            if (istream != null) {
  +                hconn.setDoOutput(true);
  +                hconn.setRequestMethod("PUT");
  +                if (contentType != null) {
  +                    hconn.setRequestProperty("Content-Type", contentType);
  +                }
  +                if (contentLength >= 0) {
  +                    hconn.setRequestProperty("Content-Length",
  +                                             "" + contentLength);
  +                }
  +            } else {
  +                hconn.setDoOutput(false);
  +                hconn.setRequestMethod("GET");
  +            }
  +            hconn.setRequestProperty("User-Agent",
  +                                     "Catalina-Ant-Task/1.0");
   
               // Set up an authorization header with our credentials
               String input = username + ":" + password;
               String output = new String(Base64.encode(input.getBytes()));
  -            conn.setRequestProperty("Authorization",
  -                                    "Basic " + output);
  +            hconn.setRequestProperty("Authorization",
  +                                     "Basic " + output);
  +
  +            // Establish the connection with the server
  +            hconn.connect();
  +
  +            // Send the request data (if any)
  +            if (istream != null) {
  +                BufferedOutputStream ostream =
  +                    new BufferedOutputStream(hconn.getOutputStream(), 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();
  +                istream.close();
  +            }
   
  -            // Perform the requested command and process the output
  -            conn.connect();
  -            reader = new InputStreamReader(conn.getInputStream());
  +            // Process the response message
  +            reader = new InputStreamReader(hconn.getInputStream());
               StringBuffer buff = new StringBuffer();
               String error = null;
               boolean first = true;
  @@ -216,6 +273,7 @@
               if (error != null) {
                   throw new BuildException(error);
               }
  +
           } catch (Throwable t) {
               throw new BuildException(t);
           } finally {
  @@ -226,6 +284,14 @@
                       ;
                   }
                   reader = null;
  +            }
  +            if (istream != null) {
  +                try {
  +                    istream.close();
  +                } catch (Throwable u) {
  +                    ;
  +                }
  +                istream = null;
               }
           }
   
  
  
  
  1.2       +5 -4      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/InstallTask.java
  
  Index: InstallTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/InstallTask.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- InstallTask.java	11 Jan 2002 00:37:30 -0000	1.1
  +++ InstallTask.java	12 Feb 2002 22:14:01 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/InstallTask.java,v 1.1 2002/01/11 00:37:30 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/01/11 00:37:30 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/InstallTask.java,v 1.2 2002/02/12 22:14:01 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/12 22:14:01 $
    *
    * ====================================================================
    *
  @@ -72,7 +72,8 @@
    * Tomcat manager application.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2002/01/11 00:37:30 $
  + * @version $Revision: 1.2 $ $Date: 2002/02/12 22:14:01 $
  + * @since 4.1
    */
   public class InstallTask extends AbstractCatalinaTask {
   
  
  
  
  1.2       +5 -4      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/ListTask.java
  
  Index: ListTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/ListTask.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ListTask.java	11 Jan 2002 00:37:30 -0000	1.1
  +++ ListTask.java	12 Feb 2002 22:14:01 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/ListTask.java,v 1.1 2002/01/11 00:37:30 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/01/11 00:37:30 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/ListTask.java,v 1.2 2002/02/12 22:14:01 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/12 22:14:01 $
    *
    * ====================================================================
    *
  @@ -72,7 +72,8 @@
    * Tomcat manager application.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2002/01/11 00:37:30 $
  + * @version $Revision: 1.2 $ $Date: 2002/02/12 22:14:01 $
  + * @since 4.1
    */
   public class ListTask extends AbstractCatalinaTask {
   
  
  
  
  1.2       +5 -4      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/ReloadTask.java
  
  Index: ReloadTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/ReloadTask.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReloadTask.java	11 Jan 2002 00:37:30 -0000	1.1
  +++ ReloadTask.java	12 Feb 2002 22:14:01 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/ReloadTask.java,v 1.1 2002/01/11 00:37:30 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/01/11 00:37:30 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/ReloadTask.java,v 1.2 2002/02/12 22:14:01 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/12 22:14:01 $
    *
    * ====================================================================
    *
  @@ -72,7 +72,8 @@
    * Tomcat manager application.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2002/01/11 00:37:30 $
  + * @version $Revision: 1.2 $ $Date: 2002/02/12 22:14:01 $
  + * @since 4.1
    */
   public class ReloadTask extends AbstractCatalinaTask {
   
  
  
  
  1.2       +5 -4      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/StartTask.java
  
  Index: StartTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/StartTask.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StartTask.java	11 Jan 2002 00:37:30 -0000	1.1
  +++ StartTask.java	12 Feb 2002 22:14:01 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/StartTask.java,v 1.1 2002/01/11 00:37:30 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/01/11 00:37:30 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/StartTask.java,v 1.2 2002/02/12 22:14:01 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/12 22:14:01 $
    *
    * ====================================================================
    *
  @@ -72,7 +72,8 @@
    * Tomcat manager application.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2002/01/11 00:37:30 $
  + * @version $Revision: 1.2 $ $Date: 2002/02/12 22:14:01 $
  + * @since 4.1
    */
   public class StartTask extends AbstractCatalinaTask {
   
  
  
  
  1.2       +5 -4      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/StopTask.java
  
  Index: StopTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/StopTask.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StopTask.java	11 Jan 2002 00:37:30 -0000	1.1
  +++ StopTask.java	12 Feb 2002 22:14:01 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/StopTask.java,v 1.1 2002/01/11 00:37:30 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/01/11 00:37:30 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/StopTask.java,v 1.2 2002/02/12 22:14:01 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/12 22:14:01 $
    *
    * ====================================================================
    *
  @@ -72,7 +72,8 @@
    * Tomcat manager application.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2002/01/11 00:37:30 $
  + * @version $Revision: 1.2 $ $Date: 2002/02/12 22:14:01 $
  + * @since 4.1
    */
   public class StopTask extends AbstractCatalinaTask {
   
  
  
  
  1.1                  jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/DeployTask.java
  
  Index: DeployTask.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/DeployTask.java,v 1.1 2002/02/12 22:14:01 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/12 22:14:01 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  
  package org.apache.catalina.ant;
  
  
  import java.io.BufferedInputStream;
  import java.io.IOException;
  import java.net.URL;
  import java.net.URLConnection;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.Task;
  
  
  /**
   * Ant task that implements the <code>/deploy</code> command, supported by
   * the Tomcat manager application.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2002/02/12 22:14:01 $
   * @since 4.1
   */
  public class DeployTask extends AbstractCatalinaTask {
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * The context path of the web application we are managing.
       */
      protected String path = null;
  
      public String getPath() {
          return (this.path);
      }
  
      public void setPath(String path) {
          this.path = path;
      }
  
  
      /**
       * URL of the web application archive (WAR) file to be deployed.
       */
      protected String war = null;
  
      public String getWar() {
          return (this.war);
      }
  
      public void setWar(String war) {
          this.war = war;
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Execute the requested operation.
       *
       * @exception BuildException if an error occurs
       */
      public void execute() throws BuildException {
  
          super.execute();
          if (path == null) {
              throw new BuildException
                  ("Must specify 'path' attribute");
          }
          if (war == null) {
              throw new BuildException
                  ("Must specify 'war' attribute");
          }
          BufferedInputStream stream = null;
          int contentLength = -1;
          try {
              URL url = new URL(war);
              URLConnection conn = url.openConnection();
              contentLength = conn.getContentLength();
              stream = new BufferedInputStream(conn.getInputStream(), 1024);
          } catch (IOException e) {
              throw new BuildException(e);
          }
          execute("/deploy?path=" + this.path, stream,
                  "application/octet-stream", contentLength);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/UndeployTask.java
  
  Index: UndeployTask.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/ant/UndeployTask.java,v 1.1 2002/02/12 22:14:01 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/12 22:14:01 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  
  package org.apache.catalina.ant;
  
  
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.Task;
  
  
  /**
   * Ant task that implements the <code>/undeploy</code> command, supported by
   * the Tomcat manager application.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2002/02/12 22:14:01 $
   * @since 4.1
   */
  public class UndeployTask extends AbstractCatalinaTask {
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * The context path of the web application we are managing.
       */
      protected String path = null;
  
      public String getPath() {
          return (this.path);
      }
  
      public void setPath(String path) {
          this.path = path;
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Execute the requested operation.
       *
       * @exception BuildException if an error occurs
       */
      public void execute() throws BuildException {
  
          super.execute();
          if (path == null) {
              throw new BuildException
                  ("Must specify 'path' attribute");
          }
          execute("/undeploy?path=" + this.path);
  
      }
  
  
  }
  
  
  
  1.11      +7 -0      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/LocalStrings.properties,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- LocalStrings.properties	5 Jan 2002 00:15:36 -0000	1.10
  +++ LocalStrings.properties	12 Feb 2002 22:14:02 -0000	1.11
  @@ -9,17 +9,23 @@
   invokerServlet.notNamed=Cannot call invoker servlet with a named dispatcher
   invokerServlet.noWrapper=Container has not called setWrapper() for this servlet
   managerServlet.alreadyContext=FAIL - Application already exists at path {0}
  +managerServlet.alreadyDocBase=FAIL - Directory {0} is already in use
   managerServlet.cannotInvoke=Cannot invoke manager servlet through invoker
   managerServlet.configured=OK - Installed application from context file {0}
  +managerServlet.deployed=OK - Deployed application at context path {0}
   managerServlet.exception=FAIL - Encountered exception {0}
   managerServlet.installed=OK - Installed application at context path {0}
   managerServlet.invalidPath=FAIL - Invalid context path {0} was specified
   managerServlet.invalidWar=FAIL - Invalid application URL {0} was specified
   managerServlet.listed=OK - Listed applications for virtual host {0}
   managerServlet.listitem={0}:{1}:{2}
  +managerServlet.noAppBase=FAIL - Cannot identify application base for context path {0}
   managerServlet.noCommand=FAIL - No command was specified
   managerServlet.noContext=FAIL - No context exists for path {0}
  +managerServlet.noDirectory=FAIL - Non-directory document base for path {0}
  +managerServlet.noDocBase=FAIL - Cannot remove document base for path {0}
   managerServlet.noPath=FAIL - No context path was specified
  +managerServlet.noRename=FAIL - Cannot deploy uploaded WAR for path {0}
   managerServlet.noRole=FAIL - User does not possess role {0}
   managerServlet.noWrapper=Container has not called setWrapper() for this servlet
   managerServlet.reloaded=OK - Reloaded application at context path {0}
  @@ -30,6 +36,7 @@
   managerServlet.started=OK - Started application at context path {0}
   managerServlet.startFailed=FAIL - Application at context path {0} could not be started
   managerServlet.stopped=OK - Stopped application at context path {0}
  +managerServlet.undeployed=OK - Undeployed application at context path {0}
   managerServlet.unknownCommand=FAIL - Unknown command {0}
   webdavservlet.jaxpfailed=JAXP initialization failed
   directory.filename=Filename
  
  
  
  1.12      +356 -16   jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/ManagerServlet.java
  
  Index: ManagerServlet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/ManagerServlet.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- ManagerServlet.java	5 Jan 2002 00:15:36 -0000	1.11
  +++ ManagerServlet.java	12 Feb 2002 22:14:02 -0000	1.12
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/ManagerServlet.java,v 1.11 2002/01/05 00:15:36 craigmcc Exp $
  - * $Revision: 1.11 $
  - * $Date: 2002/01/05 00:15:36 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/ManagerServlet.java,v 1.12 2002/02/12 22:14:02 craigmcc Exp $
  + * $Revision: 1.12 $
  + * $Date: 2002/02/12 22:14:02 $
    *
    * ====================================================================
    *
  @@ -65,10 +65,18 @@
   package org.apache.catalina.servlets;
   
   
  +import java.io.BufferedOutputStream;
  +import java.io.File;
  +import java.io.FileOutputStream;
  +import java.io.InputStream;
   import java.io.IOException;
   import java.io.PrintWriter;
   import java.net.URL;
  +import java.util.Enumeration;
  +import java.util.jar.JarEntry;
  +import java.util.jar.JarFile;
   import javax.servlet.ServletException;
  +import javax.servlet.ServletInputStream;
   import javax.servlet.UnavailableException;
   import javax.servlet.http.HttpServlet;
   import javax.servlet.http.HttpServletRequest;
  @@ -78,6 +86,7 @@
   import org.apache.catalina.Context;
   import org.apache.catalina.Deployer;
   import org.apache.catalina.Globals;
  +import org.apache.catalina.Host;
   import org.apache.catalina.Session;
   import org.apache.catalina.Wrapper;
   import org.apache.catalina.util.StringManager;
  @@ -126,6 +135,13 @@
    *     context path <code>/xxx</code> for this virtual host.</li>
    * <li><b>/stop?path=/xxx</b> - Stop the web application attached to
    *     context path <code>/xxx</code> for this virtual host.</li>
  + * <li><b>/undeploy?path=/xxx</b> - Shutdown and remove the web application
  + *     attached to context path <code>/xxx</code> for this virtual host,
  + *     and remove the underlying WAR file or document base directory.
  + *     (<em>NOTE</em> - This is only allowed if the WAR file or document
  + *     base is stored in the <code>appBase</code> directory of this host,
  + *     typically as a result of being placed there via the <code>/deploy</code>
  + *     command.</li>
    * </ul>
    * <p>Use <code>path=/</code> for the ROOT context.</p>
    * <p>The syntax of the URL for a web application archive must conform to one
  @@ -163,7 +179,7 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.11 $ $Date: 2002/01/05 00:15:36 $
  + * @version $Revision: 1.12 $ $Date: 2002/02/12 22:14:02 $
    */
   
   public class ManagerServlet
  @@ -281,7 +297,7 @@
           response.setContentType("text/plain");
           PrintWriter writer = response.getWriter();
   
  -        // Process the requested command
  +        // Process the requested command (note - "/deploy" is not listed here)
           if (command == null) {
               writer.println(sm.getString("managerServlet.noCommand"));
           } else if (command.equals("/install")) {
  @@ -298,6 +314,53 @@
               start(writer, path);
           } else if (command.equals("/stop")) {
               stop(writer, path);
  +        } else if (command.equals("/undeploy")) {
  +            undeploy(writer, path);
  +        } else {
  +            writer.println(sm.getString("managerServlet.unknownCommand",
  +                                        command));
  +        }
  +
  +        // Finish up the response
  +        writer.flush();
  +        writer.close();
  +
  +    }
  +
  +
  +    /**
  +     * Process a PUT request for the specified resource.
  +     *
  +     * @param request The servlet request we are processing
  +     * @param response The servlet response we are creating
  +     *
  +     * @exception IOException if an input/output error occurs
  +     * @exception ServletException if a servlet-specified error occurs
  +     */
  +    public void doPut(HttpServletRequest request,
  +                      HttpServletResponse response)
  +        throws IOException, ServletException {
  +
  +        // Verify that we were not accessed using the invoker servlet
  +        if (request.getAttribute(Globals.INVOKED_ATTR) != null)
  +            throw new UnavailableException
  +                (sm.getString("managerServlet.cannotInvoke"));
  +
  +        // Identify the request parameters that we need
  +        String command = request.getPathInfo();
  +        if (command == null)
  +            command = request.getServletPath();
  +        String path = request.getParameter("path");
  +
  +        // Prepare our output writer to generate the response message
  +        response.setContentType("text/plain");
  +        PrintWriter writer = response.getWriter();
  +
  +        // Process the requested command
  +        if (command == null) {
  +            writer.println(sm.getString("managerServlet.noCommand"));
  +        } else if (command.equals("/deploy")) {
  +            deploy(writer, path, request);
           } else {
               writer.println(sm.getString("managerServlet.unknownCommand",
                                           command));
  @@ -352,6 +415,185 @@
   
   
       /**
  +     * Deploy a web application archive (included in the current request)
  +     * at the specified context path.
  +     *
  +     * @param writer Writer to render results to
  +     * @param path Context path of the application to be installed
  +     * @param request Servlet request we are processing
  +     */
  +    protected synchronized void deploy(PrintWriter writer, String path,
  +                                       HttpServletRequest request) {
  +
  +        if (debug >= 1) {
  +            log("deploy: Deploying web application at '" + path + "'");
  +        }
  +
  +        if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
  +            writer.println(sm.getString("managerServlet.invalidPath", path));
  +            return;
  +        }
  +        String displayPath = path;
  +        if (displayPath.equals("")) {
  +            displayPath = "/";
  +        }
  +
  +        // Upload the web application archive to a temporary JAR file
  +        File tempDir = (File) getServletContext().getAttribute
  +            ("javax.servlet.context.tempdir");
  +        File tempJar = new File(tempDir, "webapp.war");
  +        tempJar.delete();
  +        try {
  +            if (debug >= 2) {
  +                log("Uploading WAR file to " + tempJar);
  +            }
  +            ServletInputStream istream = request.getInputStream();
  +            BufferedOutputStream ostream =
  +                new BufferedOutputStream(new FileOutputStream(tempJar), 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();
  +            istream.close();
  +        } catch (IOException e) {
  +            log("managerServlet.upload[" + displayPath + "]", e);
  +            writer.println(sm.getString("managerServlet.exception",
  +                                        e.toString()));
  +            tempJar.delete();
  +            return;
  +        }
  +
  +        // Validate that the context path and directory name are available
  +        if (deployer.findDeployedApp(path) != null) {
  +            writer.println
  +                (sm.getString("managerServlet.alreadyContext", displayPath));
  +            tempJar.delete();
  +            return;
  +        }
  +        if (!(context.getParent() instanceof Host)) {
  +            writer.println(sm.getString("managerServlet.noAppBase",
  +                                        displayPath));
  +            tempJar.delete();
  +            return;
  +        }
  +        String appBase = ((Host) context.getParent()).getAppBase();
  +        File appBaseDir = new File(appBase);
  +        if (!appBaseDir.isAbsolute()) {
  +            appBaseDir = new File(System.getProperty("catalina.base"),
  +                                  appBase);
  +        }
  +        String docBase = displayPath.substring(1);
  +        if (docBase.length() < 1) {
  +            docBase = "_";
  +        }
  +        File docBaseDir = new File(appBaseDir, docBase);
  +        if (docBaseDir.exists()) {
  +            writer.println(sm.getString("managerServlet.alreadyDocBase",
  +                                        docBaseDir));
  +            tempJar.delete();
  +            return;
  +        }
  +        File tempBaseDir = new File(tempDir, docBase);
  +
  +        // Unpack the web application into a temporary directory
  +        try {
  +
  +            // Open the uploaded WAR file
  +            if (debug >= 2) {
  +                log("Opening WAR file " + tempJar.getPath());
  +            }
  +            JarFile jarFile = new JarFile(tempJar);
  +
  +            // Create a temporary directory
  +            if (debug >= 2) {
  +                log("deploy: Creating WAR directory " + tempBaseDir);
  +            }
  +            tempBaseDir.mkdir();
  +
  +            // Unpack the contents of the uploaded WAR file
  +            Enumeration jarEntries = jarFile.entries();
  +            while (jarEntries.hasMoreElements()) {
  +                JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
  +                String name = jarEntry.getName();
  +                int last = name.lastIndexOf('/');
  +                if (last >= 0) {
  +                    File parent = new File(tempBaseDir,
  +                                           name.substring(0, last));
  +                    parent.mkdirs();
  +                }
  +                if (name.endsWith("/")) {
  +                    continue;
  +                }
  +                InputStream istream = jarFile.getInputStream(jarEntry);
  +                deployExpand(istream, tempBaseDir, name);
  +                istream.close();
  +            }
  +            jarFile.close();
  +
  +            // Rename the temporary directory to a corresponding name
  +            // in appBase (which will cause the app to be auto-deployed)
  +            if (!tempBaseDir.renameTo(docBaseDir)) {
  +                log("Cannot rename " + tempBaseDir + " to " + docBaseDir);
  +                writer.println(sm.getString("managerServlet.noRename",
  +                                            displayPath));
  +                undeployDir(tempBaseDir);
  +                tempJar.delete();
  +                return;
  +            }
  +
  +        } catch (IOException e) {
  +            log("managerServlet.unpack[" + displayPath + "]", e);
  +            writer.println(sm.getString("managerServlet.exception",
  +                                        e.toString()));
  +            undeployDir(docBaseDir);
  +            tempJar.delete();
  +            return;
  +        }
  +
  +        // Acknowledge successful completion of this deploy command
  +        tempJar.delete();
  +        writer.println(sm.getString("managerServlet.installed",
  +                                    displayPath));
  +
  +    }
  +
  +
  +    /**
  +     * Expand the specified input stream into the specified dirctory, creating
  +     * a file named from the specified relative path.
  +     *
  +     * @param istream InputStream to be copied
  +     * @param docBaseDir Document base directory into which we are expanding
  +     * @param name Relative pathname of the file to be created
  +     *
  +     * @exception IOException if an input/output error occurs
  +     */
  +    protected void deployExpand(InputStream istream, File docBaseDir,
  +                                String name) throws IOException {
  +
  +        File file = new File(docBaseDir, name);
  +        BufferedOutputStream ostream =
  +            new BufferedOutputStream(new FileOutputStream(file));
  +        byte buffer[] = new byte[2048];
  +        while (true) {
  +            int n = istream.read(buffer);
  +            if (n <= 0) {
  +                break;
  +            }
  +            ostream.write(buffer, 0, n);
  +        }
  +        ostream.close();
  +
  +    }
  +
  +
  +    /**
        * Install an application for the specified path from the specified
        * web application archive.
        *
  @@ -395,8 +637,7 @@
                   writer.println(sm.getString("managerServlet.configured",
                                               config));
               } catch (Throwable t) {
  -                getServletContext().log("ManagerServlet.configure[" +
  -                                        config + "]", t);
  +                log("ManagerServlet.configure[" + config + "]", t);
                   writer.println(sm.getString("managerServlet.exception",
                                               t.toString()));
               }
  @@ -430,8 +671,7 @@
                   writer.println(sm.getString("managerServlet.installed",
                                               displayPath));
               } catch (Throwable t) {
  -                getServletContext().log("ManagerServlet.install[" +
  -                                        displayPath + "]", t);
  +                log("ManagerServlet.install[" + displayPath + "]", t);
                   writer.println(sm.getString("managerServlet.exception",
                                               t.toString()));
               }
  @@ -505,7 +745,7 @@
               context.reload();
               writer.println(sm.getString("managerServlet.reloaded", displayPath));
           } catch (Throwable t) {
  -            getServletContext().log("ManagerServlet.reload[" + displayPath + "]", t);
  +            log("ManagerServlet.reload[" + displayPath + "]", t);
               writer.println(sm.getString("managerServlet.exception",
                                           t.toString()));
           }
  @@ -541,8 +781,7 @@
               deployer.remove(path);
               writer.println(sm.getString("managerServlet.removed", displayPath));
           } catch (Throwable t) {
  -            getServletContext().log("ManagerServlet.remove[" + displayPath + "]",
  -                                    t);
  +            log("ManagerServlet.remove[" + displayPath + "]", t);
               writer.println(sm.getString("managerServlet.exception",
                                           t.toString()));
           }
  @@ -608,8 +847,7 @@
                   writer.println(sm.getString("managerServlet.sessiontimeout",
                                               "unlimited","" + notimeout));
           } catch (Throwable t) {
  -            getServletContext().log("ManagerServlet.sessions[" + displayPath + "]",
  -                                    t);
  +            log("ManagerServlet.sessions[" + displayPath + "]", t);
               writer.println(sm.getString("managerServlet.exception",
                                           t.toString()));
           }
  @@ -688,11 +926,113 @@
               deployer.stop(path);
               writer.println(sm.getString("managerServlet.stopped", displayPath));
           } catch (Throwable t) {
  -            getServletContext().log("ManagerServlet.stop[" + displayPath + "]",
  -                                    t);
  +            log("ManagerServlet.stop[" + displayPath + "]", t);
               writer.println(sm.getString("managerServlet.exception",
                                           t.toString()));
           }
  +
  +    }
  +
  +
  +    /**
  +     * Undeploy the web application at the specified context path.
  +     *
  +     * @param writer Writer to render to
  +     * @param path Context path of the application to be removed
  +     */
  +    protected void undeploy(PrintWriter writer, String path) {
  +
  +        if (debug >= 1)
  +            log("undeploy: Undeploying web application at '" + path + "'");
  +
  +        if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
  +            writer.println(sm.getString("managerServlet.invalidPath", path));
  +            return;
  +        }
  +        String displayPath = path;
  +        if( path.equals("/") )
  +            path = "";
  +
  +        try {
  +
  +            // Validate the Context of the specified application
  +            Context context = deployer.findDeployedApp(path);
  +            if (context == null) {
  +                writer.println(sm.getString("managerServlet.noContext",
  +                                            displayPath));
  +                return;
  +            }
  +
  +            // Validate the owning Host of this Context
  +            if (!(context.getParent() instanceof Host)) {
  +                writer.println(sm.getString("managerServlet.noAppBase",
  +                                            displayPath));
  +                return;
  +            }
  +            String appBase = ((Host) context.getParent()).getAppBase();
  +            File appBaseDir = new File(appBase);
  +            if (!appBaseDir.isAbsolute()) {
  +                appBaseDir = new File(System.getProperty("catalina.base"),
  +                                      appBase);
  +            }
  +
  +            // Validate the docBase directory of this application
  +            String docBase = context.getDocBase();
  +            File docBaseDir = new File(docBase);
  +            if (!docBaseDir.isAbsolute()) {
  +                docBaseDir = new File(appBaseDir, docBase);
  +            }
  +            if (!docBaseDir.getCanonicalPath().
  +                startsWith(appBaseDir.getCanonicalPath())) {
  +                writer.println(sm.getString("managerServlet.noDocBase",
  +                                            displayPath));
  +                return;
  +            }
  +            if (!docBaseDir.isDirectory()) {
  +                writer.println(sm.getString("managerServlet.noDirectory",
  +                                            displayPath));
  +                return;
  +            }
  +
  +            // Remove this web application and its associated docBase directory
  +            if (debug >= 2) {
  +                log("Undeploying document base " + docBaseDir);
  +            }
  +            deployer.remove(path);
  +            undeployDir(docBaseDir);
  +            writer.println(sm.getString("managerServlet.undeployed",
  +                                        displayPath));
  +
  +        } catch (Throwable t) {
  +            log("ManagerServlet.undeploy[" + displayPath + "]", t);
  +            writer.println(sm.getString("managerServlet.exception",
  +                                        t.toString()));
  +        }
  +
  +    }
  +
  +
  +    /**
  +     * Delete the specified directory, including all of its contents and
  +     * subdirectories recursively.
  +     *
  +     * @param dir File object representing the directory to be deleted
  +     */
  +    protected void undeployDir(File dir) {
  +
  +        String files[] = dir.list();
  +        if (files == null) {
  +            files = new String[0];
  +        }
  +        for (int i = 0; i < files.length; i++) {
  +            File file = new File(dir, files[i]);
  +            if (file.isDirectory()) {
  +                undeployDir(file);
  +            } else {
  +                file.delete();
  +            }
  +        }
  +        dir.delete();
   
       }
   
  
  
  
  1.8       +163 -36   jakarta-tomcat-4.0/webapps/tomcat-docs/manager-howto.xml
  
  Index: manager-howto.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/webapps/tomcat-docs/manager-howto.xml,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- manager-howto.xml	11 Jan 2002 00:37:31 -0000	1.7
  +++ manager-howto.xml	12 Feb 2002 22:14:02 -0000	1.8
  @@ -27,15 +27,21 @@
   (installed by default on context path <code>/manager</code>) that supports
   the following functions:</p>
   <ul>
  -<li>Deploy a new web application, on a specified context path, from a
  -    specified directory or WAR file pathname.</li>
  +<li>Deploy a new web application, on a specified context path, from
  +    the uploaded contents of a WAR file.</li>
  +<li>Install a new web application, which can be anywhere on the
  +    server's disks.</li>
   <li>List the currently deployed web applications, as well as the
       sessions that are currently active for those web apps.</li>
  -<li>Cause an existing application to be reloaded.</li>
  -<li>Undeploy an existing web application.</li>
  +<li>Reload an existing web application, to reflect changes in the
  +    contents of <code>/WEB-INF/classes</code> or <code>/WEB-INF/lib</code>.
  +    </li>
  +<li>Remove an installed web application.</li>
  +<li>Start a stopped application (thus making it available again).</li>
   <li>Stop an existing application (so that it becomes unavailable), but
       do not undeploy it.</li>
  -<li>Start a stopped application (thus making it available again).</li>
  +<li>Undeploy a deployed web application and delete its document base
  +    directory.</li>
   </ul>
   
   <p>Since <code>Manager</code> is itself a web application, it interacts with
  @@ -156,6 +162,10 @@
           path of a directory that contains the unpacked version of a web
           application.  This directory will be attached to the context path
           you specify without any changes.</li>
  +    <li><strong>file:/absolute/path/to/a/webapp.war</strong> - The absolute
  +        path of a web application archive (WAR) file.  This is valid
  +        <strong>only</strong> for the <code>/deploy</code> command, and is
  +        the only acceptable format to that command.</li>
       <li><strong>jar:file:/absolute/path/to/a/warfile.war!/</strong> - The
           URL to a local web application archive (WAR) file.  You can use any
           syntax that is valid for the <code>JarURLConnection</code> class
  @@ -183,6 +193,63 @@
   <subsection name="Deploy A New Application">
   
   <source>
  +http://localhost:8080/manager/deploy?path=/foo
  +</source>
  +
  +<p>Upload the web application archive (WAR) file that is specified as the
  +request data in this HTTP PUT request, install it into the <code>appBase</code>
  +directory of our corresponding virtual host, and start it on the context path
  +specified by the <code>path</code> request parameter.  The application can
  +later be undeployed (and the corresponding application directory removed)
  +by use of the <code>/undeploy</code>.</p>
  +
  +<p><strong>NOTE</strong> - Since this command requires an HTTP PUT request,
  +it is usable only from tools (such as the custom Ant tasks described below).
  +To install a new web application without copying, consider the
  +<code>/install</code> command described below.  This command is the logical
  +opposite of the <code>/undeploy</code> command.</p>
  +
  +<p>If installation and startup is successful, you will receive a response
  +like this:</p>
  +<source>
  +OK - Deployed application at context path /foo
  +</source>
  +
  +<p>Otherwise, the response will start with <code>FAIL</code> and include an
  +error message.  Possible causes for problems include:</p>
  +<ul>
  +<li><em>Application already exists at path /foo</em>
  +    <blockquote>
  +    <p>The context paths for all currently running web applications must be
  +    unique.  Therefore, you must either remove or undeploy the existing web
  +    application using this context path, or choose a different context path
  +    for the new one.</p>
  +    </blockquote></li>
  +<li><em>Encountered exception</em>
  +    <blockquote>
  +    <p>An exception was encountered trying to start the new web application.
  +    Check the Tomcat 4 logs for the details, but likely explanations include
  +    problems parsing your <code>/WEB-INF/web.xml</code> file, or missing
  +    classes encountered when initializing application event listeners and
  +    filters.</p>
  +    </blockquote></li>
  +<li><em>Invalid context path was specified</em>
  +    <blockquote>
  +    <p>The context path must start with a slash character, unless you are
  +    referencing the ROOT web application -- in which case the context path
  +    must be a zero-length string.</p>
  +    </blockquote></li>
  +<li><em>No context path was specified</em>
  +    <blockquote>
  +    The <code>path</code> parameter is required.
  +    </blockquote></li>
  +</ul>
  +
  +</subsection>
  +
  +<subsection name="Install A New Application">
  +
  +<source>
   http://localhost:8080/manager/install?path=/foo&amp;war=file:/path/to/foo
   
   http://localhost:8080/manager/install?path=/bar&amp;war=jar:file:/path/to/bar.war!/
  @@ -194,7 +261,8 @@
   scheme) for either a directory or a web application archive (WAR) file.
   The supported syntax for a URL referring to a WAR file is described on the
   Javadocs page for the <code>java.net.JarURLConnection</code> class.  Use
  -only URLs that refer to the entire WAR file.</p>
  +only URLs that refer to the entire WAR file.  This command is the logical
  +opposite of the <code>/remove</code> command.</p>
   
   <p>If installation and startup is successful, you will receive a response
   like this:</p>
  @@ -208,9 +276,9 @@
   <li><em>Application already exists at path /foo</em>
       <blockquote>
       <p>The context paths for all currently running web applications must be
  -    unique.  Therefore, you must either undeploy the existing web application
  -    using this context path, or choose a different context path for the
  -    new one.</p>
  +    unique.  Therefore, you must either remove or undeploy the existing web
  +    application using this context path, or choose a different context path
  +    for the new one.</p>
       </blockquote></li>
   <li><em>Document base does not exist or is not a readable directory</em>
       <blockquote>
  @@ -248,7 +316,7 @@
   
   </subsection>
   
  -<subsection name="List Currently Deployed Applications">
  +<subsection name="List Currently Deployed and Installed Applications">
   
   <source>
   http://localhost:8080/manager/list
  @@ -256,8 +324,8 @@
   
   <p>List the context paths, current status (<code>running</code> or
   <code>stopped</code>), and number of active sessions for all currently
  -deployed web applications.  A typical response immediately after starting
  -Tomcat might look like this:</p>
  +deployed and installed web applications.  A typical response immediately
  +after starting Tomcat might look like this:</p>
   <source>
   OK - Listed applications for virtual host localhost
   /webdav:running:0
  @@ -303,8 +371,51 @@
       </blockquote></li>
   <li><em>No context exists for path /foo</em>
       <blockquote>
  -    <p>There is no deployed application on the context path that you
  -    specified.</p>
  +    <p>There is no deployed or installed application on the context path
  +    that you specified.</p>
  +    </blockquote></li>
  +<li><em>No context path was specified</em>
  +    <blockquote>
  +    The <code>path</code> parameter is required.
  +    </blockquote></li>
  +</ul>
  +
  +</subsection>
  +
  +<subsection name="Remove an Existing Application">
  +
  +<source>
  +http://localhost:8080/manager/remove?path=/examples
  +</source>
  +
  +<p>Signal an existing application to gracefully shut itself down, and then
  +remove it from Tomcat (which also makes this context path available for
  +reuse later).  This command is the logical opposite of the
  +<code>/install</code> command.</p>
  +
  +<p>If this command succeeds, you will see a response like this:</p>
  +<source>
  +OK - Removed application at context path /examples
  +</source>
  +
  +<p>Otherwise, the response will start with <code>FAIL</code> and include an
  +error message.  Possible causes for problems include:</p>
  +<ul>
  +<li><em>Encountered exception</em>
  +    <blockquote>
  +    <p>An exception was encountered trying to remove the web application.
  +    Check the Tomcat 4 logs for the details.</p>
  +    </blockquote></li>
  +<li><em>Invalid context path was specified</em>
  +    <blockquote>
  +    <p>The context path must start with a slash character, unless you are
  +    referencing the ROOT web application -- in which case the context path
  +    must be a zero-length string.</p>
  +    </blockquote></li>
  +<li><em>No context exists for path /foo</em>
  +    <blockquote>
  +    <p>There is no deployed or installed application on the context path
  +    that you specified.</p>
       </blockquote></li>
   <li><em>No context path was specified</em>
       <blockquote>
  @@ -356,7 +467,7 @@
   <ul>
   <li><em>Encountered exception</em>
       <blockquote>
  -    <p>An exception was encountered trying to undeploy the web application.
  +    <p>An exception was encountered trying to start the web application.
       Check the Tomcat 4 logs for the details.</p>
       </blockquote></li>
   <li><em>Invalid context path was specified</em>
  @@ -367,8 +478,8 @@
       </blockquote></li>
   <li><em>No context exists for path /foo</em>
       <blockquote>
  -    <p>There is no deployed application on the context path that you
  -    specified.</p>
  +    <p>There is no deployed or installed application on the context path
  +    that you specified.</p>
       </blockquote></li>
   <li><em>No context path was specified</em>
       <blockquote>
  @@ -385,9 +496,9 @@
   </source>
   
   <p>Signal an existing application to make itself unavailable, but leave it
  -deployed.  Any request that comes in while an application is stopped will
  -see an HTTP error 404, and this application will show as "stopped" on a
  -list applications command.</p>
  +deployed or installed.  Any request that comes in while an application is
  +stopped will see an HTTP error 404, and this application will show as
  +"stopped" on a list applications command.</p>
   
   <p>If this command succeeds, you will see a response like this:</p>
   <source>
  @@ -399,7 +510,7 @@
   <ul>
   <li><em>Encountered exception</em>
       <blockquote>
  -    <p>An exception was encountered trying to undeploy the web application.
  +    <p>An exception was encountered trying to stop the web application.
       Check the Tomcat 4 logs for the details.</p>
       </blockquote></li>
   <li><em>Invalid context path was specified</em>
  @@ -410,8 +521,8 @@
       </blockquote></li>
   <li><em>No context exists for path /foo</em>
       <blockquote>
  -    <p>There is no deployed application on the context path that you
  -    specified.</p>
  +    <p>There is no deployed or installed application on the context path
  +    that you specified.</p>
       </blockquote></li>
   <li><em>No context path was specified</em>
       <blockquote>
  @@ -425,16 +536,25 @@
   <subsection name="Undeploy an Existing Application">
   
   <source>
  -http://localhost:8080/manager/remove?path=/examples
  +http://localhost:8080/manager/undeploy?path=/examples
   </source>
   
  -<p>Signal an existing application to gracefully shut itself down, and then
  +<p><strong><font color="red">WARNING</font> - This command will
  +delete the contents of the web application directory if it exists within the
  +<code>appBase</code> directory (typically "webapps") for this virtual host
  +</strong>.  If you simply want to take an application out of service,
  +you should use the <code>/remove</code> command instead.</p>
  +
  +<p>Signal an existing application to gracefully shut itself down, and
   remove it from Tomcat (which also makes this context path available for
  -reuse later).</p>
  +reuse later).  In addition, the document root directory is removed, if it
  +exists in the <code>appBase</code> directory (typically "webapps") for
  +this virtual host.  This command is the logical opposite of the
  +<code>/deploy</code> command.</p>
   
   <p>If this command succeeds, you will see a response like this:</p>
   <source>
  -OK - Removed application at context path /examples
  +OK - Undeployed application at context path /examples
   </source>
   
   <p>Otherwise, the response will start with <code>FAIL</code> and include an
  @@ -453,8 +573,8 @@
       </blockquote></li>
   <li><em>No context exists for path /foo</em>
       <blockquote>
  -    <p>There is no deployed application on the context path that you
  -    specified.</p>
  +    <p>There is no deployed or installed application on the context path
  +    that you specified.</p>
       </blockquote></li>
   <li><em>No context path was specified</em>
       <blockquote>
  @@ -508,12 +628,14 @@
     &lt;property name="password" value="mypassword"/&gt;
   
     &lt;-- Configure the custom Ant tasks for the Manager application --&gt;
  -  &lt;taskdef name="install" classname="org.apache.catalina.ant.InstallTask"/&gt;
  -  &lt;taskdef name="list"    classname="org.apache.catalina.ant.ListTask"/&gt;
  -  &lt;taskdef name="reload"  classname="org.apache.catalina.ant.ReloadTask"/&gt;
  -  &lt;taskdef name="remove"  classname="org.apache.catalina.ant.RemoveTask"/&gt;
  -  &lt;taskdef name="start"   classname="org.apache.catalina.ant.StartTask"/&gt;
  -  &lt;taskdef name="stop"    classname="org.apache.catalina.ant.StopTask"/&gt;
  +  &lt;taskdef name="deploy"   classname="org.apache.catalina.ant.DeployTask"/&gt;
  +  &lt;taskdef name="install"  classname="org.apache.catalina.ant.InstallTask"/&gt;
  +  &lt;taskdef name="list"     classname="org.apache.catalina.ant.ListTask"/&gt;
  +  &lt;taskdef name="reload"   classname="org.apache.catalina.ant.ReloadTask"/&gt;
  +  &lt;taskdef name="remove"   classname="org.apache.catalina.ant.RemoveTask"/&gt;
  +  &lt;taskdef name="start"    classname="org.apache.catalina.ant.StartTask"/&gt;
  +  &lt;taskdef name="stop"     classname="org.apache.catalina.ant.StopTask"/&gt;
  +  &lt;taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask"/&gt;
   
     &lt;-- Executable Targets --&gt;
     &lt;target name="compile" description="Compile web application"&gt;
  @@ -522,7 +644,7 @@
   
     &lt;target name="deploy" description="Deploy web application"
             depends="compile"&gt;
  -    &lt;install url="${url}" username="${username}" password="${password}"
  +    &lt;deploy url="${url}" username="${username}" password="${password}"
               path="${path}" war="file://${build}"/&gt;
     &lt;/target&gt;
   
  @@ -530,6 +652,11 @@
             depends="compile"&gt;
       &lt;reload  url="${url}" username="${username}" password="${password}"
               path="${path}" war="file://${build}"/&gt;
  +  &lt;/target&gt;
  +
  +  &lt;target name="undeploy" description="Undeploy and delete web application"&gt;
  +    &lt;deploy url="${url}" username="${username}" password="${password}"
  +            path="${path}"/&gt;
     &lt;/target&gt;
   
   &lt;/project&gt;
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>