浏览代码

HADOOP-1650. Upgrade to Jetty 6.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/core/trunk@719787 13f79535-47bb-0310-9956-ffa450edef68
Christopher Douglas 16 年之前
父节点
当前提交
ef72dd54e3
共有 29 个文件被更改,包括 222 次插入361 次删除
  1. 6 6
      .eclipse.templates/.classpath
  2. 2 0
      CHANGES.txt
  3. 1 1
      bin/hadoop
  4. 二进制
      lib/jetty-5.1.4.jar
  5. 0 0
      lib/jetty-6.1.14.LICENSE.txt
  6. 二进制
      lib/jetty-6.1.14.jar
  7. 二进制
      lib/jetty-ext/commons-el.jar
  8. 二进制
      lib/jetty-ext/jasper-compiler.jar
  9. 二进制
      lib/jetty-ext/jasper-runtime.jar
  10. 二进制
      lib/jetty-ext/jsp-api.jar
  11. 二进制
      lib/jetty-util-6.1.14.jar
  12. 二进制
      lib/jsp-2.1/core-3.1.1.jar
  13. 二进制
      lib/jsp-2.1/jsp-2.1.jar
  14. 二进制
      lib/jsp-2.1/jsp-api-2.1.jar
  15. 二进制
      lib/servlet-api-2.5-6.1.14.jar
  16. 二进制
      lib/servlet-api.jar
  17. 6 7
      src/contrib/hdfsproxy/build.xml
  18. 10 15
      src/contrib/hdfsproxy/src/java/org/apache/hadoop/hdfsproxy/HdfsProxy.java
  19. 32 204
      src/contrib/hdfsproxy/src/java/org/apache/hadoop/hdfsproxy/ProxyHttpServer.java
  20. 1 1
      src/contrib/hdfsproxy/src/test/org/apache/hadoop/hdfsproxy/TestHdfsProxy.java
  21. 132 84
      src/core/org/apache/hadoop/http/HttpServer.java
  22. 1 0
      src/hdfs/org/apache/hadoop/hdfs/server/datanode/DataNode.java
  23. 2 0
      src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
  24. 2 2
      src/hdfs/org/apache/hadoop/hdfs/server/namenode/NameNode.java
  25. 2 2
      src/hdfs/org/apache/hadoop/hdfs/server/namenode/SecondaryNameNode.java
  26. 2 2
      src/mapred/org/apache/hadoop/mapred/JobTracker.java
  27. 2 2
      src/mapred/org/apache/hadoop/mapred/TaskTracker.java
  28. 2 1
      src/test/org/apache/hadoop/http/TestGlobalFilter.java
  29. 19 34
      src/test/org/apache/hadoop/mapred/NotificationTestCase.java

+ 6 - 6
.eclipse.templates/.classpath

@@ -21,16 +21,16 @@
 	<classpathentry kind="lib" path="lib/commons-net-1.4.1.jar"/>
 	<classpathentry kind="lib" path="lib/hsqldb-1.8.0.10.jar"/>
 	<classpathentry kind="lib" path="lib/jets3t-0.6.1.jar"/>
-	<classpathentry kind="lib" path="lib/jetty-5.1.4.jar"/>
-	<classpathentry kind="lib" path="lib/jetty-ext/commons-el.jar"/>
-	<classpathentry kind="lib" path="lib/jetty-ext/jasper-compiler.jar"/>
-	<classpathentry kind="lib" path="lib/jetty-ext/jasper-runtime.jar"/>
-	<classpathentry kind="lib" path="lib/jetty-ext/jsp-api.jar"/>
 	<classpathentry kind="lib" path="lib/junit-3.8.1.jar"/>
 	<classpathentry kind="lib" path="lib/kfs-0.2.2.jar"/>
 	<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
 	<classpathentry kind="lib" path="lib/oro-2.0.8.jar"/>
-	<classpathentry kind="lib" path="lib/servlet-api.jar"/>
+  <classpathentry kind="lib" path="lib/jetty-6.1.14.jar"/>
+  <classpathentry kind="lib" path="lib/jetty-util-6.1.14.jar"/>
+  <classpathentry kind="lib" path="lib/servlet-api-2.5-6.1.14.jar"/>
+  <classpathentry kind="lib" path="lib/jsp-2.1/core-3.1.1.jar"/>
+  <classpathentry kind="lib" path="lib/jsp-2.1/jsp-2.1.jar"/>
+  <classpathentry kind="lib" path="lib/jsp-2.1/jsp-api-2.1.jar"/>
 	<classpathentry kind="lib" path="lib/slf4j-api-1.4.3.jar"/>
 	<classpathentry kind="lib" path="lib/slf4j-log4j12-1.4.3.jar"/>
 	<classpathentry kind="lib" path="lib/xmlenc-0.52.jar"/>

+ 2 - 0
CHANGES.txt

@@ -33,6 +33,8 @@ Trunk (unreleased changes)
     HADOOP-4188. Removes task's dependency on concrete filesystems.
     (Sharad Agarwal via ddas)
 
+    HADOOP-1650. Upgrade to Jetty 6. (cdouglas)
+
   NEW FEATURES
 
     HADOOP-4575. Add a proxy service for relaying HsftpFileSystem requests.

+ 1 - 1
bin/hadoop

@@ -142,7 +142,7 @@ for f in $HADOOP_HOME/lib/*.jar; do
   CLASSPATH=${CLASSPATH}:$f;
 done
 
-for f in $HADOOP_HOME/lib/jetty-ext/*.jar; do
+for f in $HADOOP_HOME/lib/jsp-2.1/*.jar; do
   CLASSPATH=${CLASSPATH}:$f;
 done
 

二进制
lib/jetty-5.1.4.jar


+ 0 - 0
lib/jetty-5.1.4.LICENSE.txt → lib/jetty-6.1.14.LICENSE.txt


二进制
lib/jetty-6.1.14.jar


二进制
lib/jetty-ext/commons-el.jar


二进制
lib/jetty-ext/jasper-compiler.jar


二进制
lib/jetty-ext/jasper-runtime.jar


二进制
lib/jetty-ext/jsp-api.jar


二进制
lib/jetty-util-6.1.14.jar


二进制
lib/jsp-2.1/core-3.1.1.jar


二进制
lib/jsp-2.1/jsp-2.1.jar


二进制
lib/jsp-2.1/jsp-api-2.1.jar


二进制
lib/servlet-api-2.5-6.1.14.jar


二进制
lib/servlet-api.jar


+ 6 - 7
src/contrib/hdfsproxy/build.xml

@@ -78,19 +78,18 @@
 			<fileset dir="${hadoop.root}/lib">
         <include name="commons-logging-1.0.4.jar"/>
         <include name="commons-logging-api-1.0.4.jar"/>
-        <include name="jetty-5.1.4.jar"/>
         <include name="junit-3.8.1.jar"/>
         <include name="log4j-1.2.15.jar"/>
-        <include name="servlet-api.jar"/>
         <include name="slf4j-api-1.4.3.jar"/>
         <include name="slf4j-log4j12-1.4.3.jar"/>
         <include name="xmlenc-0.52.jar"/>
+        <include name="jetty-6.1.14.jar"/>
+        <include name="servlet-api-2.5-6.1.14.jar"/>
 			</fileset>
-			<fileset dir="${hadoop.root}/lib/jetty-ext">
-        <include name="commons-el.jar"/>
-        <include name="jasper-compiler.jar"/>
-        <include name="jasper-runtime.jar"/>
-        <include name="jsp-api.jar"/>
+			<fileset dir="${hadoop.root}/lib/jsp-2.1">
+        <include name="core-3.1.1.jar"/>
+        <include name="jsp-2.1.jar"/>
+        <include name="jsp-api-2.1.jar"/>
 			</fileset>
 		</copy>
 

+ 10 - 15
src/contrib/hdfsproxy/src/java/org/apache/hadoop/hdfsproxy/HdfsProxy.java

@@ -64,7 +64,10 @@ public class HdfsProxy {
     InetSocketAddress nnAddr = NetUtils.createSocketAddr(nn);
     LOG.info("HDFS NameNode is at: " + nnAddr.getHostName() + ":" + nnAddr.getPort());
 
-    this.server = new ProxyHttpServer();
+    Configuration sslConf = new Configuration(false);
+    sslConf.addResource(conf.get("hdfsproxy.https.server.keystore.resource",
+        "ssl-server.xml"));
+    this.server = new ProxyHttpServer(sslAddr, sslConf);
     this.server.setAttribute("proxy.https.port", sslAddr.getPort());
     this.server.setAttribute("name.node.address", nnAddr);
     this.server.setAttribute("name.conf", new Configuration());
@@ -74,18 +77,9 @@ public class HdfsProxy {
     this.server.addServlet("streamFile", "/streamFile/*", ProxyStreamFile.class);
   }
   
-  /** add an SSL listener */
-  private void addSslListener(Configuration conf) throws IOException {
-    Configuration sslConf = new Configuration(false);
-    sslConf.addResource(conf.get("hdfsproxy.https.server.keystore.resource",
-        "ssl-server.xml"));
-    server.addSslListener(sslAddr, sslConf);
-  }
-  
   /** add an http listener, only for testing purposes */
-  void addListener(InetSocketAddress addr, boolean findPort)
-      throws IOException {
-    this.server.addListener(addr, findPort);
+  void setListener(InetSocketAddress addr) throws IOException {
+    this.server.setListener(addr);
     LOG.warn("An HTTP listener is attached to the proxy server. " +
     		"It should only be used for testing purposes.");
   }
@@ -113,7 +107,8 @@ public class HdfsProxy {
         server.stop();
         server.join();
       }
-    } catch (InterruptedException ie) {
+    } catch (Exception e) {
+      LOG.warn("Got exception shutting down proxy", e);
     }
   }
   
@@ -209,7 +204,7 @@ public class HdfsProxy {
         "ssl.server.keystore.type", "jks"));
   }
 
-  private static InetSocketAddress getSslAddr(Configuration conf) throws IOException {
+  static InetSocketAddress getSslAddr(Configuration conf) throws IOException {
     String addr = conf.get("hdfsproxy.https.address");
     if (addr == null)
       throw new IOException("HdfsProxy address is not specified");
@@ -275,7 +270,7 @@ public class HdfsProxy {
 
     StringUtils.startupShutdownMessage(HdfsProxy.class, argv, LOG);
     HdfsProxy proxy = new HdfsProxy(conf);
-    proxy.addSslListener(conf);
+    //proxy.addSslListener(conf);
     proxy.start();
     return proxy;
   }

+ 32 - 204
src/contrib/hdfsproxy/src/java/org/apache/hadoop/hdfsproxy/ProxyHttpServer.java

@@ -27,226 +27,54 @@ import javax.servlet.http.HttpServlet;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.HttpServer;
 
-import org.mortbay.http.SocketListener;
-import org.mortbay.http.SslListener;
-import org.mortbay.jetty.servlet.Dispatcher;
-import org.mortbay.jetty.servlet.FilterHolder;
-import org.mortbay.jetty.servlet.WebApplicationContext;
-import org.mortbay.jetty.servlet.WebApplicationHandler;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.security.SslSocketConnector;
 
 /**
  * Create a Jetty embedded server to answer http/https requests.
  */
-public class ProxyHttpServer {
+public class ProxyHttpServer extends HttpServer {
   public static final Log LOG = LogFactory.getLog(ProxyHttpServer.class);
 
-  protected final org.mortbay.jetty.Server webServer;
-  protected final WebApplicationContext webAppContext;
-  protected SslListener sslListener;
-  protected SocketListener listener;
-  protected boolean findPort;
-
-  /**
-   * Create a status server on the given port.
-   * 
-   * @param name
-   *            The name of the server
-   * @param port
-   *            The port to use on the server
-   * @param conf
-   *            Configuration
-   */
-  public ProxyHttpServer() throws IOException {
-    webServer = new org.mortbay.jetty.Server();
-    webAppContext = webServer.addWebApplication("/", "/");
-  }
-
-  /**
-   * Add a servlet to the server.
-   * 
-   * @param name
-   *            The name of the servlet (can be passed as null)
-   * @param pathSpec
-   *            The path spec for the servlet
-   * @param clazz
-   *            The servlet class
-   */
-  public void addServlet(String name, String pathSpec,
-      Class<? extends HttpServlet> clazz) {
-    try {
-      if (name == null) {
-        webAppContext.addServlet(pathSpec, clazz.getName());
-      } else {
-        webAppContext.addServlet(name, pathSpec, clazz.getName());
-      }
-    } catch (ClassNotFoundException cnfe) {
-      throw new RuntimeException("Problem instantiating class", cnfe);
-    } catch (InstantiationException ie) {
-      throw new RuntimeException("Problem instantiating class", ie);
-    } catch (IllegalAccessException iae) {
-      throw new RuntimeException("Problem instantiating class", iae);
-    }
-  }
-
-  /** add a global filter */
-  public void addGlobalFilter(String name, String classname,
-      Map<String, String> parameters) {
-    final String[] ALL_URLS = { "/*" };
-    defineFilter(webAppContext, name, classname, parameters, ALL_URLS);
-    LOG.info("Added global filter" + name + " (class=" + classname + ")");
-  }
-
-  /**
-   * Define a filter for a context and set up default url mappings.
-   */
-  protected void defineFilter(WebApplicationContext ctx, String name,
-      String classname, Map<String, String> parameters, String[] urls) {
-    WebApplicationHandler handler = ctx.getWebApplicationHandler();
-    FilterHolder holder = handler.defineFilter(name, classname);
-    if (parameters != null) {
-      for (Map.Entry<String, String> e : parameters.entrySet()) {
-        holder.setInitParameter(e.getKey(), e.getValue());
-      }
-    }
-    for (String url : urls) {
-      handler.addFilterPathMapping(url, name, Dispatcher.__ALL);
-    }
-  }
-
-  /**
-   * Set a value in the webapp context.
-   * 
-   * @param name
-   *            The name of the attribute
-   * @param value
-   *            The value of the attribute
-   */
-  public void setAttribute(String name, Object value) {
-    webAppContext.setAttribute(name, value);
-  }
-
-  /**
-   * Get the value in the webapp context.
-   * 
-   * @param name
-   *            The name of the attribute
-   * @return The value of the attribute
-   */
-  public Object getAttribute(String name) {
-    return webAppContext.getAttribute(name);
-  }
-
-  /** return the http port that the server is on */
-  public int getPort() throws IOException {
-    if (listener == null)
-      throw new IOException("No http listerner found");
-    return listener.getPort();
-  }
-
-  public void setThreads(int min, int max) {
-    sslListener.setMinThreads(min);
-    sslListener.setMaxThreads(max);
-  }
-
-  /**
-   * Configure an http listener on the server
-   * 
-   * @param addr
-   *            address to listen on
-   * @param findPort
-   *            whether the listener should bind the given port and increment by
-   *            1 until it finds a free port
-   */
-  public void addListener(InetSocketAddress addr, boolean findPort)
+  public ProxyHttpServer(InetSocketAddress addr, Configuration conf)
       throws IOException {
-    if (listener != null || webServer.isStarted()) {
-      throw new IOException("Failed to add listener");
-    }
-    this.findPort = findPort;
-    listener = new SocketListener();
-    listener.setHost(addr.getHostName());
-    listener.setPort(addr.getPort());
-    webServer.addListener(listener);
+    super("", addr.getHostName(), addr.getPort(), 0 <= addr.getPort(), conf);
   }
 
-  /**
-   * Configure an ssl listener on the server.
-   * 
-   * @param addr
-   *            address to listen on
-   * @param sslConf
-   *            conf to retrieve SSL properties from
-   */
-  public void addSslListener(InetSocketAddress addr, Configuration sslConf)
+  /** {@inheritDoc} */
+  protected Connector createBaseListener(Configuration conf)
       throws IOException {
-    if (sslListener != null || webServer.isStarted()) {
-      throw new IOException("Failed to add ssl listener");
-    }
-    sslListener = new SslListener();
-    sslListener.setHost(addr.getHostName());
-    sslListener.setPort(addr.getPort());
-    sslListener.setKeystore(sslConf.get("ssl.server.keystore.location"));
-    sslListener.setPassword(sslConf.get("ssl.server.keystore.password", ""));
-    sslListener.setKeyPassword(sslConf.get("ssl.server.keystore.keypassword",
-        ""));
-    sslListener.setKeystoreType(sslConf.get("ssl.server.keystore.type", "jks"));
+    SslSocketConnector sslListener = new SslSocketConnector();
+    sslListener.setKeystore(conf.get("ssl.server.keystore.location"));
+    sslListener.setPassword(conf.get("ssl.server.keystore.password", ""));
+    sslListener.setKeyPassword(conf.get("ssl.server.keystore.keypassword", ""));
+    sslListener.setKeystoreType(conf.get("ssl.server.keystore.type", "jks"));
     sslListener.setNeedClientAuth(true);
-    webServer.addListener(sslListener);
-    System.setProperty("javax.net.ssl.trustStore", sslConf
-        .get("ssl.server.truststore.location"));
-    System.setProperty("javax.net.ssl.trustStorePassword", sslConf.get(
-        "ssl.server.truststore.password", ""));
-    System.setProperty("javax.net.ssl.trustStoreType", sslConf.get(
-        "ssl.server.truststore.type", "jks"));
+    System.setProperty("javax.net.ssl.trustStore",
+        conf.get("ssl.server.truststore.location", ""));
+    System.setProperty("javax.net.ssl.trustStorePassword",
+        conf.get("ssl.server.truststore.password", ""));
+    System.setProperty("javax.net.ssl.trustStoreType",
+        conf.get("ssl.server.truststore.type", "jks"));
+    return sslListener;
   }
 
   /**
-   * Start the server. Does not wait for the server to start.
+   * Configure an http listener on the server. Intended solely for unit testing.
+   *
+   * @param addr address to listen on
    */
-  public void start() throws IOException {
-    try {
-      while (true) {
-        try {
-          webServer.start();
-          break;
-        } catch (org.mortbay.util.MultiException ex) {
-          // if the multi exception contains ONLY a bind exception,
-          // then try the next port number.
-          boolean needNewPort = false;
-          if (ex.size() == 1) {
-            Exception sub = ex.getException(0);
-            if (sub instanceof java.net.BindException) {
-              if (!findPort || listener == null)
-                throw sub; // java.net.BindException
-              needNewPort = true;
-            }
-          }
-          if (!needNewPort)
-            throw ex;
-          listener.setPort(listener.getPort() + 1);
-        }
-      }
-    } catch (IOException ie) {
-      throw ie;
-    } catch (Exception e) {
-      IOException ie = new IOException("Problem starting http server");
-      ie.initCause(e);
-      throw ie;
+  void setListener(InetSocketAddress addr) throws IOException {
+    if (webServer.isStarted()) {
+      throw new IOException("Failed to add listener");
     }
-  }
-
-  /**
-   * stop the server
-   */
-  public void stop() throws InterruptedException {
-    webServer.stop();
-  }
-
-  /**
-   * wait for the server
-   */
-  public void join() throws InterruptedException {
-    webServer.join();
+    SelectChannelConnector testlistener = new SelectChannelConnector();
+    testlistener.setUseDirectBuffers(false);
+    testlistener.setHost(addr.getHostName());
+    testlistener.setPort(addr.getPort());
+    webServer.setConnectors(new Connector[] { testlistener });
   }
 }

+ 1 - 1
src/contrib/hdfsproxy/src/test/org/apache/hadoop/hdfsproxy/TestHdfsProxy.java

@@ -228,7 +228,7 @@ public class TestHdfsProxy extends TestCase {
 
         proxy = new HdfsProxy(proxyConf);
         InetSocketAddress proxyAddr = NetUtils.createSocketAddr("127.0.0.1:0");
-        proxy.addListener(proxyAddr, true);
+        proxy.setListener(proxyAddr);
         proxy.start();
         final String realProxyAddr = proxyAddr.getHostName() + ":"
             + proxy.getPort();

+ 132 - 84
src/core/org/apache/hadoop/http/HttpServer.java

@@ -19,12 +19,13 @@ package org.apache.hadoop.http;
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.net.BindException;
 import java.net.InetSocketAddress;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.HashMap;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -36,12 +37,22 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.log.LogLevel;
 import org.apache.hadoop.util.ReflectionUtils;
-import org.mortbay.http.SocketListener;
-import org.mortbay.http.SslListener;
-import org.mortbay.jetty.servlet.Dispatcher;
+
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Handler;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.ContextHandlerCollection;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.security.SslSocketConnector;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.DefaultServlet;
 import org.mortbay.jetty.servlet.FilterHolder;
-import org.mortbay.jetty.servlet.WebApplicationContext;
-import org.mortbay.jetty.servlet.WebApplicationHandler;
+import org.mortbay.jetty.servlet.FilterMapping;
+import org.mortbay.jetty.servlet.ServletHandler;
+import org.mortbay.jetty.servlet.ServletHolder;
+import org.mortbay.jetty.webapp.WebAppContext;
+import org.mortbay.thread.QueuedThreadPool;
+import org.mortbay.util.MultiException;
 
 /**
  * Create a Jetty embedded server to answer http requests. The primary goal
@@ -57,19 +68,18 @@ public class HttpServer implements FilterContainer {
   static final String FILTER_INITIALIZER_PROPERTY
       = "hadoop.http.filter.initializers";
 
-  protected final org.mortbay.jetty.Server webServer;
-  protected final WebApplicationContext webAppContext;
-  protected final Map<WebApplicationContext, Boolean> defaultContexts = 
-      new HashMap<WebApplicationContext, Boolean>();
+  protected final Server webServer;
+  protected final Connector listener;
+  protected final WebAppContext webAppContext;
   protected final boolean findPort;
-  protected final SocketListener listener;
-  private SslListener sslListener;
+  protected final Map<Context, Boolean> defaultContexts =
+      new HashMap<Context, Boolean>();
   protected final List<String> filterNames = new ArrayList<String>();
 
   /** Same as this(name, bindAddress, port, findPort, null); */
   public HttpServer(String name, String bindAddress, int port, boolean findPort
       ) throws IOException {
-    this(name, bindAddress, port, findPort, null);
+    this(name, bindAddress, port, findPort, new Configuration());
   }
 
   /**
@@ -83,16 +93,26 @@ public class HttpServer implements FilterContainer {
    */
   public HttpServer(String name, String bindAddress, int port,
       boolean findPort, Configuration conf) throws IOException {
-    webServer = new org.mortbay.jetty.Server();
+    webServer = new Server();
     this.findPort = findPort;
-    listener = new SocketListener();
-    listener.setPort(port);
+
+    listener = createBaseListener(conf);
     listener.setHost(bindAddress);
-    webServer.addListener(listener);
+    listener.setPort(port);
+    webServer.addConnector(listener);
+
+    webServer.setThreadPool(new QueuedThreadPool());
 
     final String appDir = getWebAppsPath();
-    webAppContext = webServer.addWebApplication("/", appDir + "/" + name);
-    addDefaultApps(appDir);
+    ContextHandlerCollection contexts = new ContextHandlerCollection();
+    webServer.setHandler(contexts);
+
+    webAppContext = new WebAppContext();
+    webAppContext.setContextPath("/");
+    webAppContext.setWar(appDir + "/" + name);
+    webServer.addHandler(webAppContext);
+
+    addDefaultApps(contexts, appDir);
 
     final FilterInitializer[] initializers = getFilterInitializers(conf); 
     if (initializers != null) {
@@ -103,6 +123,21 @@ public class HttpServer implements FilterContainer {
     addDefaultServlets();
   }
 
+  /**
+   * Create a required listener for the Jetty instance listening on the port
+   * provided. This wrapper and all subclasses must create at least one
+   * listener.
+   */
+  protected Connector createBaseListener(Configuration conf)
+      throws IOException {
+    SelectChannelConnector ret = new SelectChannelConnector();
+    ret.setLowResourceMaxIdleTime(10000);
+    ret.setAcceptQueueSize(128);
+    ret.setResolveNames(false);
+    ret.setUseDirectBuffers(false);
+    return ret;
+  }
+
   /** Get an array of FilterConfiguration specified in the conf */
   private static FilterInitializer[] getFilterInitializers(Configuration conf) {
     if (conf == null) {
@@ -127,15 +162,21 @@ public class HttpServer implements FilterContainer {
    * @param appDir The application directory
    * @throws IOException
    */
-  protected void addDefaultApps(final String appDir) throws IOException {
+  protected void addDefaultApps(ContextHandlerCollection parent,
+      final String appDir) throws IOException {
     // set up the context for "/logs/" if "hadoop.log.dir" property is defined. 
     String logDir = System.getProperty("hadoop.log.dir");
     if (logDir != null) {
-      addContext("/logs/*", logDir, true);
+      Context logContext = new Context(parent, "/logs");
+      logContext.setResourceBase(logDir);
+      logContext.addServlet(DefaultServlet.class, "/");
+      defaultContexts.put(logContext, true);
     }
-
     // set up the context for "/static/*"
-    addContext("/static/*", appDir + "/static", true);
+    Context staticContext = new Context(parent, "/static");
+    staticContext.setResourceBase(appDir + "/static");
+    staticContext.addServlet(DefaultServlet.class, "/*");
+    defaultContexts.put(staticContext, true);
   }
   
   /**
@@ -147,6 +188,12 @@ public class HttpServer implements FilterContainer {
     addServlet("logLevel", "/logLevel", LogLevel.Servlet.class);
   }
 
+  public void addContext(Context ctxt, boolean isFiltered)
+      throws IOException {
+    webServer.addHandler(ctxt);
+    defaultContexts.put(ctxt, isFiltered);
+  }
+
   /**
    * Add a context 
    * @param pathSpec The path spec for the context
@@ -155,8 +202,13 @@ public class HttpServer implements FilterContainer {
    * @throws IOException
    */
   protected void addContext(String pathSpec, String dir, boolean isFiltered) throws IOException {
-    WebApplicationContext webAppCtx = webServer.addWebApplication(pathSpec, dir);
-    defaultContexts.put(webAppCtx, isFiltered);
+    if (0 == webServer.getHandlers().length) {
+      throw new RuntimeException("Couldn't find handler");
+    }
+    WebAppContext webAppCtx = new WebAppContext();
+    webAppCtx.setContextPath(pathSpec);
+    webAppCtx.setWar(dir);
+    addContext(webAppCtx, true);
   }
 
   /**
@@ -191,19 +243,11 @@ public class HttpServer implements FilterContainer {
   @Deprecated
   public void addInternalServlet(String name, String pathSpec,
       Class<? extends HttpServlet> clazz) {
-    try {
-      if (name == null) {
-        webAppContext.addServlet(pathSpec, clazz.getName());
-      } else {
-        webAppContext.addServlet(name, pathSpec, clazz.getName());
-      } 
-    } catch (ClassNotFoundException cnfe) {
-      throw new RuntimeException("Problem instantiating class", cnfe);
-    } catch (InstantiationException ie) {
-      throw new RuntimeException("Problem instantiating class", ie);
-    } catch (IllegalAccessException iae) {
-      throw new RuntimeException("Problem instantiating class", iae);
+    ServletHolder holder = new ServletHolder(clazz);
+    if (name != null) {
+      holder.setName(name);
     }
+    webAppContext.addServlet(holder, pathSpec);
   }
 
   /** {@inheritDoc} */
@@ -212,15 +256,13 @@ public class HttpServer implements FilterContainer {
 
     final String[] USER_FACING_URLS = { "*.html", "*.jsp" };
     defineFilter(webAppContext, name, classname, parameters, USER_FACING_URLS);
-
     final String[] ALL_URLS = { "/*" };
-    for (Map.Entry<WebApplicationContext, Boolean> e : defaultContexts
-        .entrySet()) {
+    for (Map.Entry<Context, Boolean> e : defaultContexts.entrySet()) {
       if (e.getValue()) {
-        WebApplicationContext ctx = e.getKey();
+        Context ctx = e.getKey();
         defineFilter(ctx, name, classname, parameters, ALL_URLS);
         LOG.info("Added filter " + name + " (class=" + classname
-            + ") to context " + ctx.getName());
+            + ") to context " + ctx.getDisplayName());
       }
     }
     filterNames.add(name);
@@ -231,7 +273,7 @@ public class HttpServer implements FilterContainer {
       Map<String, String> parameters) {
     final String[] ALL_URLS = { "/*" };
     defineFilter(webAppContext, name, classname, parameters, ALL_URLS);
-    for (WebApplicationContext ctx : defaultContexts.keySet()) {
+    for (Context ctx : defaultContexts.keySet()) {
       defineFilter(ctx, name, classname, parameters, ALL_URLS);
     }
     LOG.info("Added global filter" + name + " (class=" + classname + ")");
@@ -240,20 +282,19 @@ public class HttpServer implements FilterContainer {
   /**
    * Define a filter for a context and set up default url mappings.
    */
-  protected void defineFilter(WebApplicationContext ctx, String name,
-      String classname, Map<String, String> parameters, String[] urls) {
-
-    WebApplicationHandler handler = ctx.getWebApplicationHandler();
-    FilterHolder holder = handler.defineFilter(name, classname);
-    if (parameters != null) {
-      for(Map.Entry<String, String> e : parameters.entrySet()) {
-        holder.setInitParameter(e.getKey(), e.getValue());
-      }
-    }
-
-    for (String url : urls) {
-      handler.addFilterPathMapping(url, name, Dispatcher.__ALL);
-    }
+  protected void defineFilter(Context ctx, String name,
+      String classname, Map<String,String> parameters, String[] urls) {
+
+    FilterHolder holder = new FilterHolder();
+    holder.setName(name);
+    holder.setClassName(classname);
+    holder.setInitParameters(parameters);
+    FilterMapping fmap = new FilterMapping();
+    fmap.setPathSpecs(urls);
+    fmap.setDispatches(Handler.ALL);
+    fmap.setFilterName(name);
+    ServletHandler handler = ctx.getServletHandler();
+    handler.addFilter(holder, fmap);
   }
 
   /**
@@ -261,10 +302,15 @@ public class HttpServer implements FilterContainer {
    * @param pathSpec The path spec
    * @param webAppCtx The WebApplicationContext to add to
    */
-  protected void addFilterPathMapping(String pathSpec, WebApplicationContext webAppCtx) {
-    WebApplicationHandler handler = webAppCtx.getWebApplicationHandler();
+  protected void addFilterPathMapping(String pathSpec,
+      Context webAppCtx) {
+    ServletHandler handler = webAppCtx.getServletHandler();
     for(String name : filterNames) {
-      handler.addFilterPathMapping(pathSpec, name, Dispatcher.__ALL);
+      FilterMapping fmap = new FilterMapping();
+      fmap.setPathSpec(pathSpec);
+      fmap.setFilterName(name);
+      fmap.setDispatches(Handler.ALL);
+      handler.addFilterMapping(fmap);
     }
   }
   
@@ -294,12 +340,16 @@ public class HttpServer implements FilterContainer {
    * @return the port
    */
   public int getPort() {
-    return listener.getPort();
+    return webServer.getConnectors()[0].getLocalPort();
   }
 
+  /**
+   * Set the min, max number of worker threads (simultaneous connections).
+   */
   public void setThreads(int min, int max) {
-    listener.setMinThreads(min);
-    listener.setMaxThreads(max);
+    QueuedThreadPool pool = (QueuedThreadPool) webServer.getThreadPool() ;
+    pool.setMinThreads(min);
+    pool.setMaxThreads(max);
   }
 
   /**
@@ -313,16 +363,16 @@ public class HttpServer implements FilterContainer {
   @Deprecated
   public void addSslListener(InetSocketAddress addr, String keystore,
       String storPass, String keyPass) throws IOException {
-    if (sslListener != null || webServer.isStarted()) {
+    if (webServer.isStarted()) {
       throw new IOException("Failed to add ssl listener");
     }
-    sslListener = new SslListener();
+    SslSocketConnector sslListener = new SslSocketConnector();
     sslListener.setHost(addr.getHostName());
     sslListener.setPort(addr.getPort());
     sslListener.setKeystore(keystore);
     sslListener.setPassword(storPass);
     sslListener.setKeyPassword(keyPass);
-    webServer.addListener(sslListener);
+    webServer.addConnector(sslListener);
   }
 
   /**
@@ -333,7 +383,7 @@ public class HttpServer implements FilterContainer {
    */
   public void addSslListener(InetSocketAddress addr, Configuration sslConf,
       boolean needClientAuth) throws IOException {
-    if (sslListener != null || webServer.isStarted()) {
+    if (webServer.isStarted()) {
       throw new IOException("Failed to add ssl listener");
     }
     if (needClientAuth) {
@@ -345,7 +395,7 @@ public class HttpServer implements FilterContainer {
       System.setProperty("javax.net.ssl.trustStoreType", sslConf.get(
           "ssl.server.truststore.type", "jks"));
     }
-    sslListener = new SslListener();
+    SslSocketConnector sslListener = new SslSocketConnector();
     sslListener.setHost(addr.getHostName());
     sslListener.setPort(addr.getPort());
     sslListener.setKeystore(sslConf.get("ssl.server.keystore.location"));
@@ -353,7 +403,7 @@ public class HttpServer implements FilterContainer {
     sslListener.setKeyPassword(sslConf.get("ssl.server.keystore.keypassword", ""));
     sslListener.setKeystoreType(sslConf.get("ssl.server.keystore.type", "jks"));
     sslListener.setNeedClientAuth(needClientAuth);
-    webServer.addListener(sslListener);
+    webServer.addConnector(sslListener);
   }
 
   /**
@@ -365,39 +415,37 @@ public class HttpServer implements FilterContainer {
         try {
           webServer.start();
           break;
-        } catch (org.mortbay.util.MultiException ex) {
+        } catch (MultiException ex) {
           // if the multi exception contains ONLY a bind exception,
           // then try the next port number.
-          boolean needNewPort = false;
-          if(ex.size() == 1) {
-            Exception sub = ex.getException(0);
-            if (sub instanceof java.net.BindException) {
-              if(!findPort)
-                throw sub; // java.net.BindException
-              needNewPort = true;
+          if (ex.size() == 1 && ex.getThrowable(0) instanceof BindException) {
+            if (!findPort) {
+              throw (BindException) ex.getThrowable(0);
             }
-          }
-          if (!needNewPort)
+          } else {
             throw ex;
-          listener.setPort(listener.getPort() + 1);
+          }
         }
+        listener.setPort(listener.getLocalPort() + 1);
       }
     } catch (IOException ie) {
       throw ie;
     } catch (Exception e) {
-      IOException ie = new IOException("Problem starting http server");
-      ie.initCause(e);
-      throw ie;
+      throw new IOException("Problem starting http server", e);
     }
   }
 
   /**
    * stop the server
    */
-  public void stop() throws InterruptedException {
+  public void stop() throws Exception {
     webServer.stop();
   }
 
+  public void join() throws InterruptedException {
+    webServer.join();
+  }
+
   /**
    * A very simple servlet to serve up a text representation of the current
    * stack traces. It both returns the stacks to the caller and logs them.

+ 1 - 0
src/hdfs/org/apache/hadoop/hdfs/server/datanode/DataNode.java

@@ -544,6 +544,7 @@ public class DataNode extends Configured
       try {
         infoServer.stop();
       } catch (Exception e) {
+        LOG.warn("Exception shutting down DataNode", e);
       }
     }
     if (ipcServer != null) {

+ 2 - 0
src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

@@ -463,6 +463,8 @@ public class FSNamesystem implements FSConstants, FSNamesystemMBean {
       if (replthread != null) replthread.interrupt();
       if (dnthread != null) dnthread.interrupt();
       if (smmthread != null) smmthread.interrupt();
+    } catch (Exception e) {
+      LOG.warn("Exception shutting down FSNamesystem", e);
     } finally {
       // using finally to ensure we also wait for lease daemon
       try {

+ 2 - 2
src/hdfs/org/apache/hadoop/hdfs/server/namenode/NameNode.java

@@ -271,8 +271,8 @@ public class NameNode implements ClientProtocol, DatanodeProtocol,
     stopRequested = true;
     try {
       if (httpServer != null) httpServer.stop();
-    } catch (InterruptedException ie) {
-      LOG.error(StringUtils.stringifyException(ie));
+    } catch (Exception e) {
+      LOG.error(StringUtils.stringifyException(e));
     }
     if(namesystem != null) namesystem.close();
     if(emptier != null) emptier.interrupt();

+ 2 - 2
src/hdfs/org/apache/hadoop/hdfs/server/namenode/SecondaryNameNode.java

@@ -182,8 +182,8 @@ public class SecondaryNameNode implements Runnable {
     shouldRun = false;
     try {
       if (infoServer != null) infoServer.stop();
-    } catch(InterruptedException ie) {
-      LOG.warn(StringUtils.stringifyException(ie));
+    } catch (Exception e) {
+      LOG.warn("Exception shutting down SecondaryNameNode", e);
     }
     try {
       if (checkpointImage != null) checkpointImage.close();

+ 2 - 2
src/mapred/org/apache/hadoop/mapred/JobTracker.java

@@ -1317,8 +1317,8 @@ public class JobTracker implements MRConstants, InterTrackerProtocol,
       LOG.info("Stopping infoServer");
       try {
         this.infoServer.stop();
-      } catch (InterruptedException ex) {
-        ex.printStackTrace();
+      } catch (Exception ex) {
+        LOG.warn("Exception shutting down JobTracker", ex);
       }
     }
     if (this.interTrackerServer != null) {

+ 2 - 2
src/mapred/org/apache/hadoop/mapred/TaskTracker.java

@@ -781,8 +781,8 @@ public class TaskTracker
       try {
         LOG.info("Shutting down StatusHttpServer");
         this.server.stop();
-      } catch (InterruptedException ex) {
-        ex.printStackTrace();
+      } catch (Exception e) {
+        LOG.warn("Exception shutting down TaskTracker", e);
       }
     }
   }

+ 2 - 1
src/test/org/apache/hadoop/http/TestGlobalFilter.java

@@ -147,7 +147,8 @@ public class TestGlobalFilter extends junit.framework.TestCase {
       if (counts[i] == 0) {
         assertFalse(COUNTS.containsKey(urls[i]));
       } else {
-        assertEquals(counts[i], COUNTS.remove(urls[i]).intValue());
+        assertEquals("url[" + i + "]=" + urls[i],
+            Integer.valueOf(counts[i]), COUNTS.remove(urls[i]));
       }
     }
     assertTrue(COUNTS.isEmpty());

+ 19 - 34
src/test/org/apache/hadoop/mapred/NotificationTestCase.java

@@ -18,10 +18,9 @@
 
 package org.apache.hadoop.mapred;
 
-import org.mortbay.http.HttpServer;
-import org.mortbay.http.SocketListener;
-import org.mortbay.http.HttpContext;
-import org.mortbay.jetty.servlet.ServletHandler;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.ServletHolder;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.io.Text;
@@ -65,48 +64,34 @@ public abstract class NotificationTestCase extends HadoopTestCase {
   private String contextPath = "/notification";
   private Class servletClass = NotificationServlet.class;
   private String servletPath = "/mapred";
-  private HttpServer server;
+  private Server webServer;
 
   private void startHttpServer() throws Exception {
 
-    // Create the server
-    if (server != null) {
-      server.stop();
-      server = null;
+    // Create the webServer
+    if (webServer != null) {
+      webServer.stop();
+      webServer = null;
     }
-    server = new HttpServer();
+    webServer = new Server(0);
 
-    // Create a port listener
-    SocketListener listener = new SocketListener();
-    listener.setPort(0); // letting OS to pickup the PORT
-    server.addListener(listener);
-
-    // create context
-    HttpContext context = new HttpContext();
-    context.setContextPath(contextPath + "/*");
+    Context context = new Context(webServer, contextPath);
 
     // create servlet handler
-    ServletHandler handler = new ServletHandler();
-    handler.addServlet(servletClass.getName(), servletPath,
-                       servletClass.getName());
-
-    // bind servlet handler to context
-    context.addHandler(handler);
-
-    // bind context to servlet engine
-    server.addContext(context);
+    context.addServlet(new ServletHolder(new NotificationServlet()),
+                       servletPath);
 
-    // Start server
-    server.start();
-    port = listener.getPort();
+    // Start webServer
+    webServer.start();
+    port = webServer.getConnectors()[0].getLocalPort();
 
   }
 
   private void stopHttpServer() throws Exception {
-    if (server != null) {
-      server.stop();
-      server.destroy();
-      server = null;
+    if (webServer != null) {
+      webServer.stop();
+      webServer.destroy();
+      webServer = null;
     }
   }