Repository: hbase Updated Branches: refs/heads/master a8bb27b2e -> 0ac5d4a71
http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java index be8e98f..84c1fea 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java @@ -27,6 +27,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; @@ -63,35 +64,31 @@ import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authentication.server.AuthenticationFilter; import org.apache.hadoop.security.authorize.AccessControlList; import org.apache.hadoop.util.Shell; - -import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.server.RequestLog; -import org.eclipse.jetty.server.handler.RequestLogHandler; -import org.eclipse.jetty.servlet.FilterMapping; -import org.eclipse.jetty.servlet.ServletHandler; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.DefaultServlet; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.MultiException; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.eclipse.jetty.webapp.WebAppContext; - -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.servlet.ServletContainer; +import org.mortbay.io.Buffer; +import org.mortbay.jetty.Connector; +import org.mortbay.jetty.Handler; +import org.mortbay.jetty.MimeTypes; +import org.mortbay.jetty.RequestLog; +import org.mortbay.jetty.Server; +import org.mortbay.jetty.handler.ContextHandler; +import org.mortbay.jetty.handler.ContextHandlerCollection; +import org.mortbay.jetty.handler.HandlerCollection; +import org.mortbay.jetty.handler.RequestLogHandler; +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.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; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import com.sun.jersey.spi.container.servlet.ServletContainer; /** * Create a Jetty embedded server to answer http requests. The primary goal @@ -107,8 +104,6 @@ public class HttpServer implements FilterContainer { private static final Log LOG = LogFactory.getLog(HttpServer.class); private static final String EMPTY_STRING = ""; - private static final int DEFAULT_MAX_HEADER_SIZE = 64 * 1024; // 64K - static final String FILTER_INITIALIZERS_PROPERTY = "hbase.http.filter.initializers"; static final String HTTP_MAX_THREADS = "hbase.http.max.threads"; @@ -152,8 +147,8 @@ public class HttpServer implements FilterContainer { * listener in stop(). */ private final boolean isManaged; - private final ServerConnector listener; - private ListenerInfo(boolean isManaged, ServerConnector listener) { + private final Connector listener; + private ListenerInfo(boolean isManaged, Connector listener) { this.isManaged = isManaged; this.listener = listener; } @@ -163,8 +158,8 @@ public class HttpServer implements FilterContainer { protected final WebAppContext webAppContext; protected final boolean findPort; - protected final Map<ServletContextHandler, Boolean> defaultContexts = - new HashMap<ServletContextHandler, Boolean>(); + protected final Map<Context, Boolean> defaultContexts = + new HashMap<Context, Boolean>(); protected final List<String> filterNames = new ArrayList<String>(); static final String STATE_DESCRIPTION_ALIVE = " - alive"; static final String STATE_DESCRIPTION_NOT_LIVE = " - not live"; @@ -174,6 +169,7 @@ public class HttpServer implements FilterContainer { */ public static class Builder { private ArrayList<URI> endpoints = Lists.newArrayList(); + private Connector connector; private Configuration conf; private String[] pathSpecs; private AccessControlList adminsAcl; @@ -298,6 +294,11 @@ public class HttpServer implements FilterContainer { return this; } + public Builder setConnector(Connector connector) { + this.connector = connector; + return this; + } + public Builder setPathSpec(String[] pathSpec) { this.pathSpecs = pathSpec; return this; @@ -355,15 +356,17 @@ public class HttpServer implements FilterContainer { try { endpoints.add(0, new URI("http", "", bindAddress, port, "", "", "")); } catch (URISyntaxException e) { - throw new HadoopIllegalArgumentException("Invalid endpoint: "+ e); } + throw new HadoopIllegalArgumentException("Invalid endpoint: "+ e); + } } - if (endpoints.isEmpty()) { + if (endpoints.isEmpty() && connector == null) { throw new HadoopIllegalArgumentException("No endpoints specified"); } if (hostName == null) { - hostName = endpoints.get(0).getHost(); + hostName = endpoints.isEmpty() ? connector.getHost() : endpoints.get( + 0).getHost(); } if (this.conf == null) { @@ -377,53 +380,37 @@ public class HttpServer implements FilterContainer { signatureSecretFileKey); } + if (connector != null) { + server.addUnmanagedListener(connector); + } + for (URI ep : endpoints) { - ServerConnector listener = null; + Connector listener = null; String scheme = ep.getScheme(); - HttpConfiguration httpConfig = new HttpConfiguration(); - httpConfig.setSecureScheme("https"); - httpConfig.setHeaderCacheSize(DEFAULT_MAX_HEADER_SIZE); - httpConfig.setResponseHeaderSize(DEFAULT_MAX_HEADER_SIZE); - httpConfig.setRequestHeaderSize(DEFAULT_MAX_HEADER_SIZE); - if ("http".equals(scheme)) { - listener = new ServerConnector(server.webServer, new HttpConnectionFactory(httpConfig)); + listener = HttpServer.createDefaultChannelConnector(); } else if ("https".equals(scheme)) { - HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); - httpsConfig.addCustomizer(new SecureRequestCustomizer()); - SslContextFactory sslCtxFactory = new SslContextFactory(); - sslCtxFactory.setNeedClientAuth(needsClientAuth); - sslCtxFactory.setKeyManagerPassword(keyPassword); + SslSocketConnector c = new SslSocketConnectorSecure(); + c.setNeedClientAuth(needsClientAuth); + c.setKeyPassword(keyPassword); if (keyStore != null) { - sslCtxFactory.setKeyStorePath(keyStore); - sslCtxFactory.setKeyStoreType(keyStoreType); - sslCtxFactory.setKeyStorePassword(keyStorePassword); + c.setKeystore(keyStore); + c.setKeystoreType(keyStoreType); + c.setPassword(keyStorePassword); } if (trustStore != null) { - sslCtxFactory.setTrustStorePath(trustStore); - sslCtxFactory.setTrustStoreType(trustStoreType); - sslCtxFactory.setTrustStorePassword(trustStorePassword); - + c.setTruststore(trustStore); + c.setTruststoreType(trustStoreType); + c.setTrustPassword(trustStorePassword); } - listener = new ServerConnector(server.webServer, new SslConnectionFactory(sslCtxFactory, - HttpVersion.HTTP_1_1.toString()), new HttpConnectionFactory(httpsConfig)); + listener = c; + } else { throw new HadoopIllegalArgumentException( "unknown scheme for endpoint:" + ep); } - - // default settings for connector - listener.setAcceptQueueSize(128); - if (Shell.WINDOWS) { - // result of setting the SO_REUSEADDR flag is different on Windows - // http://msdn.microsoft.com/en-us/library/ms740621(v=vs.85).aspx - // without this 2 NN's can start on the same machine and listen on - // the same port with indeterminate routing of incoming requests to them - listener.setReuseAddress(false); - } - listener.setHost(ep.getHost()); listener.setPort(ep.getPort() == -1 ? 0 : ep.getPort()); server.addManagedListener(listener); @@ -443,6 +430,12 @@ public class HttpServer implements FilterContainer { this(name, bindAddress, port, findPort, new Configuration()); } + @Deprecated + public HttpServer(String name, String bindAddress, int port, + boolean findPort, Configuration conf, Connector connector) throws IOException { + this(name, bindAddress, port, findPort, conf, null, connector, null); + } + /** * Create a status server on the given port. Allows you to specify the * path specifications that this server will be serving so that they will be @@ -460,7 +453,7 @@ public class HttpServer implements FilterContainer { @Deprecated public HttpServer(String name, String bindAddress, int port, boolean findPort, Configuration conf, String[] pathSpecs) throws IOException { - this(name, bindAddress, port, findPort, conf, null, pathSpecs); + this(name, bindAddress, port, findPort, conf, null, null, pathSpecs); } /** @@ -475,14 +468,14 @@ public class HttpServer implements FilterContainer { @Deprecated public HttpServer(String name, String bindAddress, int port, boolean findPort, Configuration conf) throws IOException { - this(name, bindAddress, port, findPort, conf, null, null); + this(name, bindAddress, port, findPort, conf, null, null, null); } @Deprecated public HttpServer(String name, String bindAddress, int port, boolean findPort, Configuration conf, AccessControlList adminsAcl) throws IOException { - this(name, bindAddress, port, findPort, conf, adminsAcl, null); + this(name, bindAddress, port, findPort, conf, adminsAcl, null, null); } /** @@ -495,33 +488,44 @@ public class HttpServer implements FilterContainer { * increment by 1 until it finds a free port. * @param conf Configuration * @param adminsAcl {@link AccessControlList} of the admins + * @param connector The jetty {@link Connector} to use + */ + @Deprecated + public HttpServer(String name, String bindAddress, int port, + boolean findPort, Configuration conf, AccessControlList adminsAcl, + Connector connector) throws IOException { + this(name, bindAddress, port, findPort, conf, adminsAcl, connector, null); + } + + /** + * Create a status server on the given port. + * The jsp scripts are taken from src/webapps/<name>. + * @param name The name of the server + * @param bindAddress The address for this server + * @param port The port to use on the server + * @param findPort whether the server should start at the given port and + * increment by 1 until it finds a free port. + * @param conf Configuration + * @param adminsAcl {@link AccessControlList} of the admins + * @param connector A jetty connection listener * @param pathSpecs Path specifications that this httpserver will be serving. * These will be added to any filters. */ @Deprecated public HttpServer(String name, String bindAddress, int port, boolean findPort, Configuration conf, AccessControlList adminsAcl, - String[] pathSpecs) throws IOException { + Connector connector, String[] pathSpecs) throws IOException { this(new Builder().setName(name) .addEndpoint(URI.create("http://" + bindAddress + ":" + port)) .setFindPort(findPort).setConf(conf).setACL(adminsAcl) - .setPathSpec(pathSpecs)); + .setConnector(connector).setPathSpec(pathSpecs)); } private HttpServer(final Builder b) throws IOException { this.appDir = b.appDir; this.logDir = b.logDir; final String appDir = getWebAppsPath(b.name); - - - int maxThreads = b.conf.getInt(HTTP_MAX_THREADS, -1); - // If HTTP_MAX_THREADS is not configured, QueueThreadPool() will use the - // default value (currently 250). - QueuedThreadPool threadPool = maxThreads == -1 ? new QueuedThreadPool() - : new QueuedThreadPool(maxThreads); - threadPool.setDaemon(true); - this.webServer = new Server(threadPool); - + this.webServer = new Server(); this.adminsAcl = b.adminsAcl; this.webAppContext = createWebAppContext(b.name, b.conf, adminsAcl, appDir); this.findPort = b.findPort; @@ -534,6 +538,14 @@ public class HttpServer implements FilterContainer { Preconditions.checkNotNull(webAppContext); + int maxThreads = conf.getInt(HTTP_MAX_THREADS, -1); + // If HTTP_MAX_THREADS is not configured, QueueThreadPool() will use the + // default value (currently 250). + QueuedThreadPool threadPool = maxThreads == -1 ? new QueuedThreadPool() + : new QueuedThreadPool(maxThreads); + threadPool.setDaemon(true); + webServer.setThreadPool(threadPool); + ContextHandlerCollection contexts = new ContextHandlerCollection(); RequestLog requestLog = HttpRequestLog.getRequestLog(name); @@ -549,7 +561,7 @@ public class HttpServer implements FilterContainer { final String appDir = getWebAppsPath(name); - webServer.setHandler(webAppContext); + webServer.addHandler(webAppContext); addDefaultApps(contexts, appDir, conf); @@ -577,7 +589,11 @@ public class HttpServer implements FilterContainer { } } - private void addManagedListener(ServerConnector connector) { + private void addUnmanagedListener(Connector connector) { + listeners.add(new ListenerInfo(false, connector)); + } + + private void addManagedListener(Connector connector) { listeners.add(new ListenerInfo(true, connector)); } @@ -598,6 +614,33 @@ public class HttpServer implements FilterContainer { Collections.<String, String> emptyMap(), new String[] { "/*" }); } + /** + * Create a required listener for the Jetty instance listening on the port + * provided. This wrapper and all subclasses must create at least one + * listener. + */ + public Connector createBaseListener(Configuration conf) throws IOException { + return HttpServer.createDefaultChannelConnector(); + } + + @InterfaceAudience.Private + public static Connector createDefaultChannelConnector() { + SelectChannelConnector ret = new SelectChannelConnector(); + ret.setLowResourceMaxIdleTime(10000); + ret.setAcceptQueueSize(128); + ret.setResolveNames(false); + ret.setUseDirectBuffers(false); + if(Shell.WINDOWS) { + // result of setting the SO_REUSEADDR flag is different on Windows + // http://msdn.microsoft.com/en-us/library/ms740621(v=vs.85).aspx + // without this 2 NN's can start on the same machine and listen on + // the same port with indeterminate routing of incoming requests to them + ret.setReuseAddress(false); + } + ret.setHeaderBufferSize(1024*64); + return ret; + } + /** Get an array of FilterConfiguration specified in the conf */ private static FilterInitializer[] getFilterInitializers(Configuration conf) { if (conf == null) { @@ -629,10 +672,9 @@ public class HttpServer implements FilterContainer { logDir = System.getProperty("hadoop.log.dir"); } if (logDir != null) { - ServletContextHandler logContext = new ServletContextHandler(parent, "/*"); - logContext.addServlet(AdminAuthorizedServlet.class, "/*"); + Context logContext = new Context(parent, "/logs"); logContext.setResourceBase(logDir); - + logContext.addServlet(AdminAuthorizedServlet.class, "/*"); if (conf.getBoolean( ServerConfigurationKeys.HBASE_JETTY_LOGS_SERVE_ALIASES, ServerConfigurationKeys.DEFAULT_HBASE_JETTY_LOGS_SERVE_ALIASES)) { @@ -647,7 +689,7 @@ public class HttpServer implements FilterContainer { defaultContexts.put(logContext, true); } // set up the context for "/static/*" - ServletContextHandler staticContext = new ServletContextHandler(parent, "/static"); + Context staticContext = new Context(parent, "/static"); staticContext.setResourceBase(appDir + "/static"); staticContext.addServlet(DefaultServlet.class, "/*"); staticContext.setDisplayName("static"); @@ -655,7 +697,7 @@ public class HttpServer implements FilterContainer { defaultContexts.put(staticContext, true); } - private void setContextAttributes(ServletContextHandler context, Configuration conf) { + private void setContextAttributes(Context context, Configuration conf) { context.getServletContext().setAttribute(CONF_CONTEXT_ATTRIBUTE, conf); context.getServletContext().setAttribute(ADMINS_ACL, adminsAcl); } @@ -682,6 +724,30 @@ public class HttpServer implements FilterContainer { addServlet("conf", "/conf", ConfServlet.class); } + public void addContext(Context ctxt, boolean isFiltered) + throws IOException { + webServer.addHandler(ctxt); + addNoCacheFilter(webAppContext); + defaultContexts.put(ctxt, isFiltered); + } + + /** + * Add a context + * @param pathSpec The path spec for the context + * @param dir The directory containing the context + * @param isFiltered if true, the servlet is added to the filter path mapping + * @throws IOException + */ + protected void addContext(String pathSpec, String dir, boolean isFiltered) throws IOException { + 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); + } + /** * Set a value in the webapp context. These values are available to the jsp * pages as "application.getAttribute(name)". @@ -701,9 +767,10 @@ public class HttpServer implements FilterContainer { final String pathSpec) { LOG.info("addJerseyResourcePackage: packageName=" + packageName + ", pathSpec=" + pathSpec); - - ResourceConfig application = new ResourceConfig().packages(packageName); - final ServletHolder sh = new ServletHolder(new ServletContainer(application)); + final ServletHolder sh = new ServletHolder(ServletContainer.class); + sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", + "com.sun.jersey.api.core.PackagesResourceConfig"); + sh.setInitParameter("com.sun.jersey.config.property.packages", packageName); webAppContext.addServlet(sh, pathSpec); } @@ -761,7 +828,7 @@ public class HttpServer implements FilterContainer { FilterMapping fmap = new FilterMapping(); fmap.setPathSpec(pathSpec); fmap.setFilterName(SPNEGO_FILTER); - fmap.setDispatches(FilterMapping.ALL); + fmap.setDispatches(Handler.ALL); handler.addFilterMapping(fmap); } } @@ -775,12 +842,12 @@ public class HttpServer implements FilterContainer { LOG.info("Added filter " + name + " (class=" + classname + ") to context " + webAppContext.getDisplayName()); final String[] ALL_URLS = { "/*" }; - for (Map.Entry<ServletContextHandler, Boolean> e : defaultContexts.entrySet()) { + for (Map.Entry<Context, Boolean> e : defaultContexts.entrySet()) { if (e.getValue()) { - ServletContextHandler handler = e.getKey(); - defineFilter(handler, name, classname, parameters, ALL_URLS); + Context ctx = e.getKey(); + defineFilter(ctx, name, classname, parameters, ALL_URLS); LOG.info("Added filter " + name + " (class=" + classname - + ") to context " + handler.getDisplayName()); + + ") to context " + ctx.getDisplayName()); } } filterNames.add(name); @@ -791,7 +858,7 @@ public class HttpServer implements FilterContainer { Map<String, String> parameters) { final String[] ALL_URLS = { "/*" }; defineFilter(webAppContext, name, classname, parameters, ALL_URLS); - for (ServletContextHandler ctx : defaultContexts.keySet()) { + for (Context ctx : defaultContexts.keySet()) { defineFilter(ctx, name, classname, parameters, ALL_URLS); } LOG.info("Added global filter '" + name + "' (class=" + classname + ")"); @@ -800,20 +867,19 @@ public class HttpServer implements FilterContainer { /** * Define a filter for a context and set up default url mappings. */ - public static void defineFilter(ServletContextHandler handler, String name, + public static void defineFilter(Context ctx, String name, String classname, Map<String,String> parameters, String[] urls) { FilterHolder holder = new FilterHolder(); holder.setName(name); holder.setClassName(classname); - if (parameters != null) { - holder.setInitParameters(parameters); - } + holder.setInitParameters(parameters); FilterMapping fmap = new FilterMapping(); fmap.setPathSpecs(urls); - fmap.setDispatches(FilterMapping.ALL); + fmap.setDispatches(Handler.ALL); fmap.setFilterName(name); - handler.getServletHandler().addFilter(holder, fmap); + ServletHandler handler = ctx.getServletHandler(); + handler.addFilter(holder, fmap); } /** @@ -822,13 +888,14 @@ public class HttpServer implements FilterContainer { * @param webAppCtx The WebApplicationContext to add to */ protected void addFilterPathMapping(String pathSpec, - WebAppContext webAppCtx) { + Context webAppCtx) { + ServletHandler handler = webAppCtx.getServletHandler(); for(String name : filterNames) { FilterMapping fmap = new FilterMapping(); fmap.setPathSpec(pathSpec); fmap.setFilterName(name); - fmap.setDispatches(FilterMapping.ALL); - webAppCtx.getServletHandler().addFilterMapping(fmap); + fmap.setDispatches(Handler.ALL); + handler.addFilterMapping(fmap); } } @@ -870,7 +937,7 @@ public class HttpServer implements FilterContainer { */ @Deprecated public int getPort() { - return ((ServerConnector)webServer.getConnectors()[0]).getLocalPort(); + return webServer.getConnectors()[0].getLocalPort(); } /** @@ -884,10 +951,9 @@ public class HttpServer implements FilterContainer { if (index > webServer.getConnectors().length) return null; - ServerConnector c = (ServerConnector)webServer.getConnectors()[index]; - if (c.getLocalPort() == -1 || c.getLocalPort() == -2) { - // -1 if the connector has not been opened - // -2 if it has been closed + Connector c = webServer.getConnectors()[index]; + if (c.getLocalPort() == -1) { + // The connector is not bounded return null; } @@ -1014,9 +1080,9 @@ public class HttpServer implements FilterContainer { */ void openListeners() throws Exception { for (ListenerInfo li : listeners) { - ServerConnector listener = li.listener; - if (!li.isManaged || (li.listener.getLocalPort() != -1 && li.listener.getLocalPort() != -2)) { - // This listener is either started externally, or has not been opened, or has been closed + Connector listener = li.listener; + if (!li.isManaged || li.listener.getLocalPort() != -1) { + // This listener is either started externally or has been bound continue; } int port = listener.getPort(); @@ -1119,7 +1185,7 @@ public class HttpServer implements FilterContainer { StringBuilder sb = new StringBuilder("HttpServer (") .append(isAlive() ? STATE_DESCRIPTION_ALIVE : STATE_DESCRIPTION_NOT_LIVE).append("), listening at:"); for (ListenerInfo li : listeners) { - ServerConnector l = li.listener; + Connector l = li.listener; sb.append(l.getHost()).append(":").append(l.getPort()).append("/,"); } return sb.toString(); @@ -1376,8 +1442,12 @@ public class HttpServer implements FilterContainer { */ private String inferMimeType(ServletRequest request) { String path = ((HttpServletRequest)request).getRequestURI(); - ServletContext context = config.getServletContext(); - return context.getMimeType(path); + ContextHandler.SContext sContext = (ContextHandler.SContext)config.getServletContext(); + MimeTypes mimes = sContext.getContextHandler().getMimeTypes(); + Buffer mimeBuffer = mimes.getMimeByExtension(path); + return (mimeBuffer == null) ? null : mimeBuffer.toString(); } + } + } http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/hbase-server/src/main/java/org/apache/hadoop/hbase/jetty/SslSelectChannelConnectorSecure.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/jetty/SslSelectChannelConnectorSecure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/jetty/SslSelectChannelConnectorSecure.java new file mode 100644 index 0000000..712b4f1 --- /dev/null +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/jetty/SslSelectChannelConnectorSecure.java @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable + * law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License + * for the specific language governing permissions and limitations under the License. + */ +package org.apache.hadoop.hbase.jetty; + +import java.io.IOException; +import java.util.ArrayList; + +import javax.net.ssl.SSLEngine; + +import org.mortbay.jetty.security.SslSelectChannelConnector; + +/** + * Avoid SSL V3.0 "Poodle" Vulnerability - CVE-2014-3566 + */ +public class SslSelectChannelConnectorSecure extends SslSelectChannelConnector { + @Override + protected SSLEngine createSSLEngine() throws IOException { + SSLEngine sslEngine = super.createSSLEngine(); + ArrayList<String> secureProtocols = new ArrayList<String>(); + for (String p : sslEngine.getEnabledProtocols()) { + if (!p.contains("SSLv3")) { + secureProtocols.add(p); + } + } + sslEngine.setEnabledProtocols(secureProtocols.toArray(new String[secureProtocols.size()])); + return sslEngine; + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HttpServerUtil.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HttpServerUtil.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HttpServerUtil.java index cb93982..a66251f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HttpServerUtil.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HttpServerUtil.java @@ -17,10 +17,10 @@ */ package org.apache.hadoop.hbase.util; -import org.eclipse.jetty.security.ConstraintSecurityHandler; -import org.eclipse.jetty.util.security.Constraint; -import org.eclipse.jetty.security.ConstraintMapping; -import org.eclipse.jetty.servlet.ServletContextHandler; +import org.mortbay.jetty.security.Constraint; +import org.mortbay.jetty.security.ConstraintMapping; +import org.mortbay.jetty.security.SecurityHandler; +import org.mortbay.jetty.servlet.Context; /** * HttpServer utility. @@ -28,9 +28,9 @@ import org.eclipse.jetty.servlet.ServletContextHandler; public class HttpServerUtil { /** * Add constraints to a Jetty Context to disallow undesirable Http methods. - * @param ctxHandler The context to modify + * @param context The context to modify */ - public static void constrainHttpMethods(ServletContextHandler ctxHandler) { + public static void constrainHttpMethods(Context context) { Constraint c = new Constraint(); c.setAuthenticate(true); @@ -44,9 +44,9 @@ public class HttpServerUtil { cmo.setMethod("OPTIONS"); cmo.setPathSpec("/*"); - ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); - securityHandler.setConstraintMappings(new ConstraintMapping[]{ cmt, cmo }); + SecurityHandler sh = new SecurityHandler(); + sh.setConstraintMappings(new ConstraintMapping[]{ cmt, cmo }); - ctxHandler.setSecurityHandler(securityHandler); + context.addHandler(sh); } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpRequestLog.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpRequestLog.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpRequestLog.java index b8d21d1..8fea254 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpRequestLog.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpRequestLog.java @@ -22,9 +22,8 @@ import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.log4j.Logger; import org.junit.Test; import org.junit.experimental.categories.Category; - -import org.eclipse.jetty.server.RequestLog; -import org.eclipse.jetty.server.NCSARequestLog; +import org.mortbay.jetty.NCSARequestLog; +import org.mortbay.jetty.RequestLog; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java index 3a58adc..6642638 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java @@ -70,9 +70,8 @@ import org.junit.Test; import org.junit.experimental.categories.Category; import org.mockito.Mockito; import org.mockito.internal.util.reflection.Whitebox; - -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.util.ajax.JSON; +import org.mortbay.jetty.Connector; +import org.mortbay.util.ajax.JSON; @Category({MiscTests.class, SmallTests.class}) public class TestHttpServer extends HttpServerFunctionalTest { @@ -565,7 +564,7 @@ public class TestHttpServer extends HttpServerFunctionalTest { // not bound, ephemeral should return requested port (0 for ephemeral) List<?> listeners = (List<?>) Whitebox.getInternalState(server, "listeners"); - ServerConnector listener = (ServerConnector) Whitebox.getInternalState( + Connector listener = (Connector) Whitebox.getInternalState( listeners.get(0), "listener"); assertEquals(port, listener.getPort()); @@ -624,4 +623,16 @@ public class TestHttpServer extends HttpServerFunctionalTest { assertEquals(conn.getHeaderField("Expires"), conn.getHeaderField("Date")); assertEquals("DENY", conn.getHeaderField("X-Frame-Options")); } + + /** + * HTTPServer.Builder should proceed if a external connector is available. + */ + @Test + public void testHttpServerBuilderWithExternalConnector() throws Exception { + Connector c = mock(Connector.class); + doReturn("localhost").when(c).getHost(); + HttpServer s = new HttpServer.Builder().setName("test").setConnector(c) + .build(); + s.stop(); + } } http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestServletFilter.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestServletFilter.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestServletFilter.java index cfb5ff3..5ddc6d4 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestServletFilter.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/http/TestServletFilter.java @@ -183,7 +183,7 @@ public class TestServletFilter extends HttpServerFunctionalTest { http.start(); fail("expecting exception"); } catch (IOException e) { - GenericTestUtils.assertExceptionContains("Unable to initialize WebAppContext", e); + assertTrue( e.getMessage().contains("Problem in starting http server. Server handlers failed")); } } http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/hbase-spark/pom.xml ---------------------------------------------------------------------- diff --git a/hbase-spark/pom.xml b/hbase-spark/pom.xml index 8417d2f..035dfcc 100644 --- a/hbase-spark/pom.xml +++ b/hbase-spark/pom.xml @@ -51,6 +51,7 @@ <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> + <version>3.0.1</version> <scope>test</scope> </dependency> http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/hbase-thrift/pom.xml ---------------------------------------------------------------------- diff --git a/hbase-thrift/pom.xml b/hbase-thrift/pom.xml index 4b1946b..d097f38 100644 --- a/hbase-thrift/pom.xml +++ b/hbase-thrift/pom.xml @@ -305,16 +305,38 @@ <artifactId>slf4j-api</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-server</artifactId> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jetty</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-servlet</artifactId> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jetty-sslengine</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-jsp</artifactId> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jetty-util</artifactId> + </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>servlet-api-2.5</artifactId> + </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jsp-api-2.1</artifactId> + </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jsp-2.1</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>tomcat</groupId> + <artifactId>jasper-compiler</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>tomcat</groupId> + <artifactId>jasper-runtime</artifactId> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java ---------------------------------------------------------------------- diff --git a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java index 169d42f..46ea7f8 100644 --- a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java +++ b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java @@ -48,7 +48,6 @@ import javax.security.sasl.SaslServer; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionGroup; -import org.apache.commons.lang.ArrayUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; @@ -81,6 +80,7 @@ import org.apache.hadoop.hbase.filter.Filter; import org.apache.hadoop.hbase.filter.ParseFilter; import org.apache.hadoop.hbase.filter.PrefixFilter; import org.apache.hadoop.hbase.filter.WhileMatchFilter; +import org.apache.hadoop.hbase.jetty.SslSelectChannelConnectorSecure; import org.apache.hadoop.hbase.security.SecurityUtil; import org.apache.hadoop.hbase.security.UserProvider; import org.apache.hadoop.hbase.thrift.CallQueue.Call; @@ -123,17 +123,16 @@ import org.apache.thrift.transport.TSaslServerTransport; import org.apache.thrift.transport.TServerSocket; import org.apache.thrift.transport.TServerTransport; import org.apache.thrift.transport.TTransportFactory; - -import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.server.*; +import org.mortbay.jetty.Connector; +import org.mortbay.jetty.Server; +import org.mortbay.jetty.nio.SelectChannelConnector; +import org.mortbay.jetty.servlet.Context; +import org.mortbay.jetty.servlet.ServletHolder; +import org.mortbay.thread.QueuedThreadPool; import com.google.common.base.Joiner; import com.google.common.base.Throwables; import com.google.common.util.concurrent.ThreadFactoryBuilder; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.util.thread.QueuedThreadPool; /** * ThriftServerRunner - this class starts up a Thrift server which implements @@ -144,8 +143,6 @@ public class ThriftServerRunner implements Runnable { private static final Log LOG = LogFactory.getLog(ThriftServerRunner.class); - private static final int DEFAULT_HTTP_MAX_HEADER_SIZE = 64 * 1024; // 64k - static final String SERVER_TYPE_CONF_KEY = "hbase.regionserver.thrift.server.type"; @@ -163,10 +160,6 @@ public class ThriftServerRunner implements Runnable { static final String THRIFT_SSL_KEYSTORE_STORE = "hbase.thrift.ssl.keystore.store"; static final String THRIFT_SSL_KEYSTORE_PASSWORD = "hbase.thrift.ssl.keystore.password"; static final String THRIFT_SSL_KEYSTORE_KEYPASSWORD = "hbase.thrift.ssl.keystore.keypassword"; - static final String THRIFT_SSL_EXCLUDE_CIPHER_SUITES = "hbase.thrift.ssl.exclude.cipher.suites"; - static final String THRIFT_SSL_INCLUDE_CIPHER_SUITES = "hbase.thrift.ssl.include.cipher.suites"; - static final String THRIFT_SSL_EXCLUDE_PROTOCOLS = "hbase.thrift.ssl.exclude.protocols"; - static final String THRIFT_SSL_INCLUDE_PROTOCOLS = "hbase.thrift.ssl.include.protocols"; /** * Amount of time in milliseconds before a server thread will timeout @@ -400,85 +393,53 @@ public class ThriftServerRunner implements Runnable { TServlet thriftHttpServlet = new ThriftHttpServlet(processor, protocolFactory, realUser, conf, hbaseHandler, securityEnabled, doAsEnabled); - // Set the default max thread number to 100 to limit - // the number of concurrent requests so that Thrfit HTTP server doesn't OOM easily. - // Jetty set the default max thread number to 250, if we don't set it. - // - // Our default min thread number 2 is the same as that used by Jetty. - int minThreads = conf.getInt(HTTP_MIN_THREADS, 2); - int maxThreads = conf.getInt(HTTP_MAX_THREADS, 100); - QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads); - threadPool.setMinThreads(minThreads); - httpServer = new Server(threadPool); - + httpServer = new Server(); // Context handler - ServletContextHandler ctxHandler = new ServletContextHandler(httpServer, "/", ServletContextHandler.SESSIONS); - ctxHandler.addServlet(new ServletHolder(thriftHttpServlet), "/*"); + Context context = new Context(httpServer, "/", Context.SESSIONS); + context.setContextPath("/"); + String httpPath = "/*"; + httpServer.setHandler(context); + context.addServlet(new ServletHolder(thriftHttpServlet), httpPath); // set up Jetty and run the embedded server - HttpConfiguration httpConfig = new HttpConfiguration(); - httpConfig.setSecureScheme("https"); - httpConfig.setSecurePort(listenPort); - httpConfig.setHeaderCacheSize(DEFAULT_HTTP_MAX_HEADER_SIZE); - httpConfig.setRequestHeaderSize(DEFAULT_HTTP_MAX_HEADER_SIZE); - httpConfig.setResponseHeaderSize(DEFAULT_HTTP_MAX_HEADER_SIZE); - httpConfig.setSendServerVersion(false); - httpConfig.setSendDateHeader(false); - - ServerConnector serverConnector; + Connector connector = new SelectChannelConnector(); if(conf.getBoolean(THRIFT_SSL_ENABLED, false)) { - HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); - httpsConfig.addCustomizer(new SecureRequestCustomizer()); - - SslContextFactory sslCtxFactory = new SslContextFactory(); + SslSelectChannelConnectorSecure sslConnector = new SslSelectChannelConnectorSecure(); String keystore = conf.get(THRIFT_SSL_KEYSTORE_STORE); String password = HBaseConfiguration.getPassword(conf, THRIFT_SSL_KEYSTORE_PASSWORD, null); String keyPassword = HBaseConfiguration.getPassword(conf, THRIFT_SSL_KEYSTORE_KEYPASSWORD, password); - sslCtxFactory.setKeyStorePath(keystore); - sslCtxFactory.setKeyStorePassword(password); - sslCtxFactory.setKeyManagerPassword(keyPassword); - - String[] excludeCiphers = conf.getStrings( - THRIFT_SSL_EXCLUDE_CIPHER_SUITES, ArrayUtils.EMPTY_STRING_ARRAY); - if (excludeCiphers.length != 0) { - sslCtxFactory.setExcludeCipherSuites(excludeCiphers); - } - String[] includeCiphers = conf.getStrings( - THRIFT_SSL_INCLUDE_CIPHER_SUITES, ArrayUtils.EMPTY_STRING_ARRAY); - if (includeCiphers.length != 0) { - sslCtxFactory.setIncludeCipherSuites(includeCiphers); - } - - // Disable SSLv3 by default due to "Poodle" Vulnerability - CVE-2014-3566 - String[] excludeProtocols = conf.getStrings( - THRIFT_SSL_EXCLUDE_PROTOCOLS, "SSLv3"); - if (excludeProtocols.length != 0) { - sslCtxFactory.setExcludeProtocols(excludeProtocols); - } - String[] includeProtocols = conf.getStrings( - THRIFT_SSL_INCLUDE_PROTOCOLS, ArrayUtils.EMPTY_STRING_ARRAY); - if (includeProtocols.length != 0) { - sslCtxFactory.setIncludeProtocols(includeProtocols); - } - - serverConnector = new ServerConnector(httpServer, - new SslConnectionFactory(sslCtxFactory, HttpVersion.HTTP_1_1.toString()), - new HttpConnectionFactory(httpsConfig)); - } else { - serverConnector = new ServerConnector(httpServer, new HttpConnectionFactory(httpConfig)); + sslConnector.setKeystore(keystore); + sslConnector.setPassword(password); + sslConnector.setKeyPassword(keyPassword); + connector = sslConnector; } - serverConnector.setPort(listenPort); String host = getBindAddress(conf).getHostAddress(); - serverConnector.setHost(host); - httpServer.addConnector(serverConnector); - httpServer.setStopAtShutdown(true); + connector.setPort(listenPort); + connector.setHost(host); + connector.setHeaderBufferSize(1024 * 64); + httpServer.addConnector(connector); if (doAsEnabled) { ProxyUsers.refreshSuperUserGroupsConfiguration(conf); } + // Set the default max thread number to 100 to limit + // the number of concurrent requests so that Thrfit HTTP server doesn't OOM easily. + // Jetty set the default max thread number to 250, if we don't set it. + // + // Our default min thread number 2 is the same as that used by Jetty. + int minThreads = conf.getInt(HTTP_MIN_THREADS, 2); + int maxThreads = conf.getInt(HTTP_MAX_THREADS, 100); + QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads); + threadPool.setMinThreads(minThreads); + httpServer.setThreadPool(threadPool); + + httpServer.setSendServerVersion(false); + httpServer.setSendDateHeader(false); + httpServer.setStopAtShutdown(true); + LOG.info("Starting Thrift HTTP Server on " + Integer.toString(listenPort)); } http://git-wip-us.apache.org/repos/asf/hbase/blob/0ac5d4a7/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 6d837d6..637b236 100644 --- a/pom.xml +++ b/pom.xml @@ -1235,16 +1235,12 @@ <httpcore.version>4.4.4</httpcore.version> <metrics-core.version>3.1.2</metrics-core.version> <guava.version>12.0.1</guava.version> - <jackson.version>2.23.2</jackson.version> + <jackson.version>1.9.13</jackson.version> <jasper.version>5.5.23</jasper.version> <jaxb-api.version>2.2.2</jaxb-api.version> - <jetty.version>9.3.8.v20160314</jetty.version> - <jetty-jsp.version>9.2.19.v20160908</jetty-jsp.version> - <jackson1.version>1.9.13</jackson1.version> - <servlet.api.version>3.1.0</servlet.api.version> - <jersey.version>2.22.2</jersey.version> - <jetty6.version>6.1.26</jetty6.version> + <jetty.version>6.1.26</jetty.version> <jetty.jspapi.version>6.1.14</jetty.jspapi.version> + <jersey.version>1.9</jersey.version> <jruby.version>1.6.8</jruby.version> <junit.version>4.12</junit.version> <hamcrest.version>1.3</hamcrest.version> @@ -1664,6 +1660,17 @@ <version>${jruby.version}</version> </dependency> <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jetty</artifactId> + <version>${jetty.version}</version> + <exclusions> + <exclusion> + <groupId>org.mortbay.jetty</groupId> + <artifactId>servlet-api</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> <groupId>org.jruby.jcodings</groupId> <artifactId>jcodings</artifactId> <version>${jcodings.version}</version> @@ -1673,28 +1680,63 @@ <artifactId>joni</artifactId> <version>${joni.version}</version> </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jetty-util</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jetty-sslengine</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jsp-2.1</artifactId> + <version>${jetty.jspapi.version}</version> + <exclusions> + <exclusion> + <groupId>org.eclipse.jdt</groupId> + <artifactId>core</artifactId> + </exclusion> + <exclusion> + <groupId>ant</groupId> + <artifactId>ant</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jsp-api-2.1</artifactId> + <version>${jetty.jspapi.version}</version> + </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>servlet-api-2.5</artifactId> + <version>${jetty.jspapi.version}</version> + </dependency> <!-- While jackson is also a dependency of jersey it can bring in jars from different, incompatible versions. We force the same version with these dependencies --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> - <version>${jackson1.version}</version> + <version>${jackson.version}</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> - <version>${jackson1.version}</version> + <version>${jackson.version}</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-jaxrs</artifactId> - <version>${jackson1.version}</version> + <version>${jackson.version}</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-xc</artifactId> - <version>${jackson1.version}</version> + <version>${jackson.version}</version> </dependency> <dependency> <!--If this is not in the runtime lib, we get odd @@ -1741,82 +1783,32 @@ </dependency> <!-- REST dependencies --> <dependency> - <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> - <version>${servlet.api.version}</version> + <groupId>com.google.protobuf</groupId> + <artifactId>protobuf-java</artifactId> + <version>${external.protobuf.version}</version> </dependency> <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-server</artifactId> - <version>${jetty.version}</version> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-core</artifactId> + <version>${jersey.version}</version> </dependency> <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-servlet</artifactId> - <version>${jetty.version}</version> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-json</artifactId> + <version>${jersey.version}</version> <exclusions> <exclusion> - <groupId>org.eclipse.jetty</groupId> - <artifactId>servlet-api</artifactId> + <groupId>stax</groupId> + <artifactId>stax-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-security</artifactId> - <version>${jetty.version}</version> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-http</artifactId> - <version>${jetty.version}</version> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-util</artifactId> - <version>${jetty.version}</version> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-io</artifactId> - <version>${jetty.version}</version> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-jsp</artifactId> - <version>${jetty-jsp.version}</version> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-jmx</artifactId> - <version>${jetty.version}</version> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-webapp</artifactId> - <version>${jetty.version}</version> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-util-ajax</artifactId> - <version>${jetty.version}</version> - </dependency> - <dependency> - <groupId>com.google.protobuf</groupId> - <artifactId>protobuf-java</artifactId> - <version>${external.protobuf.version}</version> - </dependency> - <dependency> - <groupId>org.glassfish.jersey.containers</groupId> - <artifactId>jersey-container-servlet-core</artifactId> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-server</artifactId> <version>${jersey.version}</version> </dependency> <dependency> - <groupId>org.glassfish.jersey.media</groupId> - <artifactId>jersey-media-json-jackson1</artifactId> - <version>${jackson.version}</version> - </dependency> - <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>${jaxb-api.version}</version> @@ -2170,10 +2162,6 @@ <groupId>io.netty</groupId> <artifactId>netty</artifactId> </exclusion> - <exclusion> - <groupId>javax.servlet</groupId> - <artifactId>servlet-api</artifactId> - </exclusion> </exclusions> </dependency> <dependency> @@ -2185,10 +2173,6 @@ <groupId>io.netty</groupId> <artifactId>netty</artifactId> </exclusion> - <exclusion> - <groupId>javax.servlet</groupId> - <artifactId>servlet-api</artifactId> - </exclusion> </exclusions> </dependency> <dependency> @@ -2202,10 +2186,6 @@ <groupId>io.netty</groupId> <artifactId>netty</artifactId> </exclusion> - <exclusion> - <groupId>javax.servlet</groupId> - <artifactId>servlet-api</artifactId> - </exclusion> </exclusions> </dependency> <dependency>
