This is an automated email from the ASF dual-hosted git repository.

nihaljain pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/master by this push:
     new 8bb4e8c6dc2 HBASE-29226 Migrate to jetty 12 with EE8 and bump java 
servlet to 4.0.1 (#6783)
8bb4e8c6dc2 is described below

commit 8bb4e8c6dc254bb05de5b1177c7b787aa8dd6067
Author: Nihal Jain <[email protected]>
AuthorDate: Fri Aug 22 15:50:31 2025 +0530

    HBASE-29226 Migrate to jetty 12 with EE8 and bump java servlet to 4.0.1 
(#6783)
    
    Please find a detailed summary of all changes as below:
    
    **Dependencies**
    - Replaced `hbase-shaded-jetty` i.e. Jetty 9 with 
`hbase-shaded-jetty-12-plus-core` and `hbase-shaded-jetty-12-plus-ee8` i.e. 
Jetty 12 EE8
    - Upgrade `servlet.api.version` to `4.0.1`
    - Upgrade `tomcat.jasper.version` to `9.0.107`
    
    **Code Adjustments**
    - Modified import statements to use `org.eclipse.jetty.ee8` etc. as per 
Jetty 12
    - Replace `HandlerCollection` with `Handler.Sequence`
      - Refer 
https://jetty.org/docs/jetty/12/programming-guide/migration/11-to-12.html#api-changes-handler-sequence
    - Adjust request log handler.
       - Refer 
https://jetty.org/docs/jetty/12/programming-guide/migration/11-to-12.html#api-changes-handler-requestlog
    - Adjust error handlers' set logic based on available methods
    - Remove usage of deprecated method `setResourceBase()` with 
`setBaseResourceAsPath()`. Also, passing `logDir` path in canonical format as 
otherwise, we get `404` in case we have `\..\` in static path.
      - Refer https://github.com/jetty/jetty.project/issues/12958
    - Remove `MultiException`  with `ExceptionUtil.MultiException` in 
`HttpServer.java`.
    - Modify assignment: `webServer.getHandlers()` with new return type: 
`Array` to `List`
    - Replaced `Constraint` with `ServletConstraint`
    - Added `LogLevelExceptionUtils.java` to handle HTML error response for log 
levels as `connection.getResponseMessage()` now returns error code as string in 
message and hence causes test failure otherwise
    - Allow `javax` as xsd files at `javax/servlet/resources` come via 
`org.apache.hbase.thirdparty:hbase-shaded-jetty-12-ee8 `
    
    **Test Adjustments**
    - Update `checkBindAddress()` to call `server.start()` else 
`testBindAddress()` fails with NPE. Verified doing same without Jetty 12 works 
as well.
    - Replace `JSON.parse()` with `new JSON().fromJSON()` and `JSON.toString()` 
with `new JSON().toJSON()`
    - Update app name from `".."` to `""` as it fails with 
`IllegalArgumentException` otherwise
    - Update `MockHttpApiRule` where we replace `AbstractHandler` with 
`Handler.Abstract` and adjust code based on new interface.
      - Refer 
https://jetty.org/docs/jetty/12/programming-guide/migration/11-to-12.html#handler-request-content-apis
    - Deleted `webdefaults.xml`. Need to see if still needed.
    - Added necessary compliance rules for URI validation, required by tests 
and possibly users as well. Add note for what fails if these rules are not 
there in tests.
      - Refer 
https://github.com/jetty/jetty.project/issues/11890#issuecomment-2156449534
    
    **References**
    - Umbrealla at HBASE-29224
    - Discussion at 
https://lists.apache.org/thread/bkrfm705kqd3bqzyvo7jv46t6p64x2n5
    - Dependent thirdparty change at 
https://github.com/apache/hbase-thirdparty/commit/fd76b1eec91d40c97c59a2a36e8f430ce05d6788
    
    Signed-off-by: Dávid Paksy <[email protected]>
    Signed-off-by: Istvan Toth <[email protected]>
---
 hbase-http/pom.xml                                 |   6 +-
 .../hadoop/hbase/http/AdminAuthorizedServlet.java  |   2 +-
 .../org/apache/hadoop/hbase/http/HttpServer.java   |  53 +-
 .../apache/hadoop/hbase/http/HttpServerUtil.java   |  12 +-
 .../org/apache/hadoop/hbase/http/InfoServer.java   |   2 +-
 .../hadoop/hbase/http/ProfileOutputServlet.java    |   2 +-
 .../org/apache/hadoop/hbase/http/log/LogLevel.java |   7 +-
 .../hbase/http/log/LogLevelExceptionUtils.java     | 100 ++++
 .../apache/hadoop/hbase/http/TestHttpServer.java   |   5 +-
 .../hadoop/hbase/http/conf/TestConfServlet.java    |   2 +-
 .../apache/hadoop/hbase/http/log/TestLogLevel.java |   5 +-
 .../hadoop/hbase/http/resource/JerseyResource.java |   2 +-
 .../org/apache/hadoop/hbase/MockHttpApiRule.java   |  65 ++-
 .../org/apache/hadoop/hbase/rest/RESTServer.java   |  24 +-
 .../hadoop/hbase/rest/TestGetAndPutResource.java   |   5 +
 .../hadoop/hbase/rest/client/TestRemoteTable.java  |  25 +
 .../org/apache/hadoop/hbase/master/HMaster.java    |   4 +-
 .../resources/ensure-jars-have-correct-contents.sh |   2 +
 .../shaded/org/eclipse/jetty/webapp/webdefault.xml | 550 ---------------------
 .../resources/ensure-jars-have-correct-contents.sh |   2 +
 .../apache/hadoop/hbase/thrift/ThriftServer.java   |   4 +-
 pom.xml                                            |  13 +-
 22 files changed, 261 insertions(+), 631 deletions(-)

diff --git a/hbase-http/pom.xml b/hbase-http/pom.xml
index 60288f49519..98f7c4e1a06 100644
--- a/hbase-http/pom.xml
+++ b/hbase-http/pom.xml
@@ -78,7 +78,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.hbase.thirdparty</groupId>
-      <artifactId>hbase-shaded-jetty</artifactId>
+      <artifactId>hbase-shaded-jetty-12-plus-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase.thirdparty</groupId>
+      <artifactId>hbase-shaded-jetty-12-plus-ee8</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.hbase.thirdparty</groupId>
diff --git 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/AdminAuthorizedServlet.java
 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/AdminAuthorizedServlet.java
index 2ad09b5ae5c..1ecd75532ce 100644
--- 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/AdminAuthorizedServlet.java
+++ 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/AdminAuthorizedServlet.java
@@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.yetus.audience.InterfaceStability;
 
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.DefaultServlet;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.DefaultServlet;
 
 /**
  * General servlet which is admin-authorized.
diff --git 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java
index 6012b24ec54..fe2a9a48c21 100644
--- a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java
+++ b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java
@@ -72,6 +72,12 @@ import org.slf4j.LoggerFactory;
 import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
 import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableMap;
 import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.DefaultServlet;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.FilterHolder;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.FilterMapping;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.ServletContextHandler;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.ServletHolder;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.webapp.WebAppContext;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.http.HttpVersion;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Handler;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.HttpConfiguration;
@@ -84,18 +90,10 @@ import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.SslConnectionFactory
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.SymlinkAllowedResourceAliasChecker;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.handler.ContextHandlerCollection;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.handler.ErrorHandler;
-import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.handler.HandlerCollection;
-import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.handler.RequestLogHandler;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.handler.gzip.GzipHandler;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.DefaultServlet;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.FilterHolder;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.FilterMapping;
-import 
org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletContextHandler;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHolder;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.util.MultiException;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.util.ExceptionUtil;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.util.ssl.SslContextFactory;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.webapp.WebAppContext;
 import org.apache.hbase.thirdparty.org.glassfish.jersey.server.ResourceConfig;
 import 
org.apache.hbase.thirdparty.org.glassfish.jersey.servlet.ServletContainer;
 
@@ -654,23 +652,21 @@ public class HttpServer implements FilterContainer {
 
     Preconditions.checkNotNull(webAppContext);
 
-    HandlerCollection handlerCollection = new HandlerCollection();
+    Handler.Sequence handlers = new Handler.Sequence();
 
     ContextHandlerCollection contexts = new ContextHandlerCollection();
     RequestLog requestLog = HttpRequestLog.getRequestLog(name);
 
     if (requestLog != null) {
-      RequestLogHandler requestLogHandler = new RequestLogHandler();
-      requestLogHandler.setRequestLog(requestLog);
-      handlerCollection.addHandler(requestLogHandler);
+      webServer.setRequestLog(requestLog);
     }
 
     final String appDir = getWebAppsPath(name);
 
-    handlerCollection.addHandler(contexts);
-    handlerCollection.addHandler(webAppContext);
+    handlers.addHandler(contexts);
+    handlers.addHandler(webAppContext);
 
-    webServer.setHandler(handlerCollection);
+    webServer.setHandler(handlers);
 
     webAppContext.setAttribute(ADMINS_ACL, adminsAcl);
 
@@ -715,8 +711,9 @@ public class HttpServer implements FilterContainer {
     // Check if disable stack trace property is configured
     if (!conf.getBoolean(HTTP_UI_SHOW_STACKTRACE_KEY, true)) {
       // Disable stack traces for server errors in UI
-      webServer.setErrorHandler(new ErrorHandler());
-      webServer.getErrorHandler().setShowStacks(false);
+      ErrorHandler errorHandler = new ErrorHandler();
+      errorHandler.setShowStacks(false);
+      webServer.setErrorHandler(errorHandler);
       // Disable stack traces for web app errors in UI
       webAppContext.getErrorHandler().setShowStacks(false);
     }
@@ -841,7 +838,8 @@ public class HttpServer implements FilterContainer {
       if 
(context.getAliasChecks().stream().anyMatch(aliasCheckerClass::isInstance)) {
         LOG.debug("{} is already part of alias check list", 
aliasCheckerClass.getName());
       } else {
-        context.addAliasCheck(new SymlinkAllowedResourceAliasChecker(context));
+        context
+          .addAliasCheck(new 
SymlinkAllowedResourceAliasChecker(context.getCoreContextHandler()));
         LOG.debug("{} added to the alias check list", 
aliasCheckerClass.getName());
       }
       LOG.info("Serving aliases allowed for /logs context");
@@ -1258,14 +1256,14 @@ public class HttpServer implements FilterContainer {
       } catch (IOException ex) {
         LOG.info("HttpServer.start() threw a non Bind IOException", ex);
         throw ex;
-      } catch (MultiException ex) {
-        LOG.info("HttpServer.start() threw a MultiException", ex);
+      } catch (Exception ex) {
+        LOG.info("HttpServer.start() threw a Exception", ex);
         throw ex;
       }
       // Make sure there is no handler failures.
-      Handler[] handlers = webServer.getHandlers();
-      for (int i = 0; i < handlers.length; i++) {
-        if (handlers[i].isFailed()) {
+      List<Handler> handlers = webServer.getHandlers();
+      for (Handler handler : handlers) {
+        if (handler.isFailed()) {
           throw new IOException("Problem in starting http server. Server 
handlers failed");
         }
       }
@@ -1335,7 +1333,7 @@ public class HttpServer implements FilterContainer {
    * stop the server
    */
   public void stop() throws Exception {
-    MultiException exception = null;
+    ExceptionUtil.MultiException exception = null;
     for (ListenerInfo li : listeners) {
       if (!li.isManaged) {
         continue;
@@ -1372,9 +1370,10 @@ public class HttpServer implements FilterContainer {
 
   }
 
-  private MultiException addMultiException(MultiException exception, Exception 
e) {
+  private ExceptionUtil.MultiException 
addMultiException(ExceptionUtil.MultiException exception,
+    Exception e) {
     if (exception == null) {
-      exception = new MultiException();
+      exception = new ExceptionUtil.MultiException();
     }
     exception.add(e);
     return exception;
diff --git 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServerUtil.java 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServerUtil.java
index ecfb32742fd..0f1c9707d1c 100644
--- a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServerUtil.java
+++ b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServerUtil.java
@@ -22,11 +22,11 @@ import javax.servlet.DispatcherType;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.yetus.audience.InterfaceAudience;
 
-import 
org.apache.hbase.thirdparty.org.eclipse.jetty.security.ConstraintMapping;
-import 
org.apache.hbase.thirdparty.org.eclipse.jetty.security.ConstraintSecurityHandler;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.FilterHolder;
-import 
org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletContextHandler;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.util.security.Constraint;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.nested.ServletConstraint;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.security.ConstraintMapping;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.security.ConstraintSecurityHandler;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.FilterHolder;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.ServletContextHandler;
 
 /**
  * HttpServer utility.
@@ -43,7 +43,7 @@ public final class HttpServerUtil {
    */
   public static void constrainHttpMethods(ServletContextHandler ctxHandler,
     boolean allowOptionsMethod) {
-    Constraint c = new Constraint();
+    ServletConstraint c = new ServletConstraint();
     c.setAuthenticate(true);
 
     ConstraintMapping cmt = new ConstraintMapping();
diff --git 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java
index ea73be808f0..5a09315ed77 100644
--- a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java
+++ b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java
@@ -29,7 +29,7 @@ import org.apache.hadoop.security.authorize.AccessControlList;
 import org.apache.yetus.audience.InterfaceAudience;
 
 import org.apache.hbase.thirdparty.com.google.common.net.HostAndPort;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHolder;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.ServletHolder;
 
 /**
  * Create a Jetty embedded server to answer http requests. The primary goal is 
to serve up status
diff --git 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/ProfileOutputServlet.java
 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/ProfileOutputServlet.java
index d92e7d009f6..12d0c462504 100644
--- 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/ProfileOutputServlet.java
+++ 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/ProfileOutputServlet.java
@@ -27,7 +27,7 @@ import org.apache.yetus.audience.InterfaceAudience;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.DefaultServlet;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.DefaultServlet;
 
 /**
  * Servlet to serve files generated by {@link ProfileServlet}
diff --git 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java
index a9e8fa7cbe1..915f7e29918 100644
--- a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java
+++ b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java
@@ -41,7 +41,6 @@ import org.apache.hadoop.hbase.logging.Log4jUtils;
 import org.apache.hadoop.security.authentication.client.AuthenticatedURL;
 import org.apache.hadoop.security.authentication.client.KerberosAuthenticator;
 import org.apache.hadoop.security.ssl.SSLFactory;
-import org.apache.hadoop.util.HttpExceptionUtils;
 import org.apache.hadoop.util.ServletUtil;
 import org.apache.hadoop.util.Tool;
 import org.apache.yetus.audience.InterfaceAudience;
@@ -267,7 +266,11 @@ public final class LogLevel {
 
       HttpURLConnection connection = connect(url);
 
-      HttpExceptionUtils.validateResponse(connection, 200);
+      // We now use the validateResponse method of hbase to handle for HTML 
response,
+      // as with Jetty 12: getResponseMessage() returns "Precondition Failed" 
vs
+      // "Modification of logger 
protected.org.apache.hadoop.hbase.http.log.TestLogLevel is
+      // disallowed in configuration" in Jetty 9
+      LogLevelExceptionUtils.validateResponse(connection, 200);
 
       // read from the servlet
 
diff --git 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevelExceptionUtils.java
 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevelExceptionUtils.java
new file mode 100644
index 00000000000..2776c9b4313
--- /dev/null
+++ 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevelExceptionUtils.java
@@ -0,0 +1,100 @@
+/*
+ * 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.http.log;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.nio.charset.StandardCharsets;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import org.apache.yetus.audience.InterfaceAudience;
+
+/**
+ * HTTP utility class to help propagate server side exception in log level 
servlet to the client
+ * over HTTP (HTML payload) It parses HTTP client connections and recreates 
the exception.
+ */
[email protected]
+public class LogLevelExceptionUtils {
+
+  private static void throwEx(Throwable ex) {
+    LogLevelExceptionUtils.<RuntimeException> throwException(ex);
+  }
+
+  @SuppressWarnings("unchecked")
+  private static <E extends Throwable> void throwException(Throwable ex) 
throws E {
+    throw (E) ex;
+  }
+
+  /**
+   * Validates the status of an <code>HttpURLConnection</code> against an 
expected HTTP status code.
+   * If the current status code is not the expected one it throws an exception 
with a detail message
+   * using Server side error messages if available.
+   * <p>
+   * <b>NOTE: This is an adapted version of the original method in 
HttpServerUtil.java of Hadoop,
+   * but we handle for HTML response.
+   * @param conn           the <code>HttpURLConnection</code>.
+   * @param expectedStatus the expected HTTP status code.
+   * @throws IOException thrown if the current status code does not match the 
expected one.
+   */
+  @SuppressWarnings("unchecked")
+  public static void validateResponse(HttpURLConnection conn, int 
expectedStatus)
+    throws IOException {
+    if (conn.getResponseCode() != expectedStatus) {
+      Exception toThrow = null;
+
+      try (InputStream es = conn.getErrorStream()) {
+        if (es != null) {
+          try (InputStreamReader isr = new InputStreamReader(es, 
StandardCharsets.UTF_8);
+            BufferedReader reader = new BufferedReader(isr)) {
+            final String errorAsHtml = 
reader.lines().collect(Collectors.joining("\n"));
+
+            final String status = extractValue(errorAsHtml, 
"<th>STATUS:</th><td>(\\d+)</td>");
+            final String message = extractValue(errorAsHtml, 
"<th>MESSAGE:</th><td>([^<]+)</td>");
+            final String uri = extractValue(errorAsHtml, 
"<th>URI:</th><td>([^<]+)</td>");
+            final String exception = extractValue(errorAsHtml, 
"<title>([^<]+)</title>");
+
+            toThrow = new IOException(
+              String.format("HTTP status [%s], message [%s], URL [%s], 
exception [%s]", status,
+                message, uri, exception));
+          }
+        }
+      } catch (Exception ex) {
+        toThrow =
+          new IOException(String.format("HTTP status [%d], message [%s], URL 
[%s], exception [%s]",
+            conn.getResponseCode(), conn.getResponseMessage(), conn.getURL(), 
ex), ex);
+      }
+      if (toThrow != null) {
+        throwEx(toThrow);
+      }
+    }
+  }
+
+  private static String extractValue(String html, String regex) {
+    Pattern pattern = Pattern.compile(regex);
+    Matcher matcher = pattern.matcher(html);
+    if (matcher.find()) {
+      return matcher.group(1);
+    }
+    return null;
+  }
+
+}
diff --git 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java
index ad9c9d3a067..72466392827 100644
--- a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java
+++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java
@@ -507,7 +507,7 @@ public class TestHttpServer extends 
HttpServerFunctionalTest {
 
   @SuppressWarnings("unchecked")
   private static Map<String, Object> parse(String jsonString) {
-    return (Map<String, Object>) JSON.parse(jsonString);
+    return (Map<String, Object>) new JSON().fromJSON(jsonString);
   }
 
   @Test
@@ -615,6 +615,9 @@ public class TestHttpServer extends 
HttpServerFunctionalTest {
       ServerConnector listener = server.getServerConnectors().get(0);
 
       assertEquals(port, listener.getPort());
+      // We are doing this as otherwise testBindAddress fails, not sure how we 
were even starting
+      // server in jetty 9 without this call
+      server.start();
       // verify hostname is what was given
       server.openListeners();
       assertEquals(host, server.getConnectorAddress(0).getHostName());
diff --git 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java
 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java
index fe202906e9c..dc14be96d40 100644
--- 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java
+++ 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java
@@ -73,7 +73,7 @@ public class TestConfServlet {
     Set<String> programSet = new HashSet<>();
     programSet.add("programatically");
     programSet.add("programmatically");
-    Object parsed = JSON.parse(json);
+    Object parsed = new JSON().fromJSON(json);
     Object[] properties = ((Map<String, Object[]>) parsed).get("properties");
     for (Object o : properties) {
       Map<String, Object> propertyInfo = (Map<String, Object>) o;
diff --git 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java
index bc45a629555..04452f613ba 100644
--- 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java
+++ 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java
@@ -235,7 +235,10 @@ public class TestLogLevel {
    * @throws Exception if unable to create or start a Jetty server
    */
   private HttpServer createServer(String protocol, boolean isSpnego) throws 
Exception {
-    HttpServer.Builder builder = new HttpServer.Builder().setName("..")
+    // Changed to "" as ".." moves it a steps back in path because the path is 
relative to the
+    // current working directory. throws "java.lang.IllegalArgumentException: 
Base Resource is not
+    // valid: hbase-http/target/test-classes/static" as it is not able to find 
the static folder.
+    HttpServer.Builder builder = new HttpServer.Builder().setName("")
       .addEndpoint(new URI(protocol + 
"://localhost:0")).setFindPort(true).setConf(serverConf);
     if (isSpnego) {
       // Set up server Kerberos credentials.
diff --git 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/resource/JerseyResource.java
 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/resource/JerseyResource.java
index 89d71b403af..4e97dcfae3f 100644
--- 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/resource/JerseyResource.java
+++ 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/resource/JerseyResource.java
@@ -54,7 +54,7 @@ public class JerseyResource {
     final Map<String, Object> m = new TreeMap<>();
     m.put(PATH, path);
     m.put(OP, op);
-    final String js = JSON.toString(m);
+    final String js = new JSON().toJSON(m);
     return Response.ok(js).type(MediaType.APPLICATION_JSON).build();
   }
 }
diff --git 
a/hbase-it/src/test/java/org/apache/hadoop/hbase/MockHttpApiRule.java 
b/hbase-it/src/test/java/org/apache/hadoop/hbase/MockHttpApiRule.java
index 5817d071f02..be50b313725 100644
--- a/hbase-it/src/test/java/org/apache/hadoop/hbase/MockHttpApiRule.java
+++ b/hbase-it/src/test/java/org/apache/hadoop/hbase/MockHttpApiRule.java
@@ -17,28 +17,31 @@
  */
 package org.apache.hadoop.hbase;
 
-import java.io.IOException;
-import java.io.PrintWriter;
 import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.function.BiConsumer;
 import java.util.regex.Pattern;
-import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.junit.rules.ExternalResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.hbase.thirdparty.javax.ws.rs.core.HttpHeaders;
 import org.apache.hbase.thirdparty.javax.ws.rs.core.MediaType;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.server.CustomRequestLog;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Handler;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Request;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.RequestLog;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Response;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.ServerConnector;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Slf4jRequestLog;
-import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.handler.AbstractHandler;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.Slf4jRequestLogWriter;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.util.Callback;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.util.RegexSet;
 
 /**
@@ -55,7 +58,7 @@ public class MockHttpApiRule extends ExternalResource {
    * Register a callback handler for the specified path target.
    */
   public MockHttpApiRule addRegistration(final String pathRegex,
-    final BiConsumer<String, HttpServletResponse> responder) {
+    final BiConsumer<String, Response> responder) {
     handler.register(pathRegex, responder);
     return this;
   }
@@ -65,16 +68,21 @@ public class MockHttpApiRule extends ExternalResource {
    */
   public MockHttpApiRule registerOk(final String pathRegex, final String 
responseBody) {
     return addRegistration(pathRegex, (target, resp) -> {
-      try {
-        resp.setStatus(HttpServletResponse.SC_OK);
-        resp.setCharacterEncoding("UTF-8");
-        resp.setContentType(MediaType.APPLICATION_JSON_TYPE.toString());
-        final PrintWriter writer = resp.getWriter();
-        writer.write(responseBody);
-        writer.flush();
-      } catch (IOException e) {
-        throw new RuntimeException(e);
-      }
+      resp.setStatus(HttpServletResponse.SC_OK);
+      resp.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "UTF-8");
+      resp.getHeaders().put(HttpHeaders.CONTENT_TYPE, 
MediaType.APPLICATION_JSON_TYPE.toString());
+      ByteBuffer content = 
ByteBuffer.wrap(responseBody.getBytes(StandardCharsets.UTF_8));
+      resp.write(true, content, new Callback() {
+        @Override
+        public void succeeded() {
+          // nothing to do
+        }
+
+        @Override
+        public void failed(Throwable x) {
+          throw new RuntimeException(x);
+        }
+      });
     });
   }
 
@@ -115,20 +123,18 @@ public class MockHttpApiRule extends ExternalResource {
   }
 
   private static RequestLog buildRequestLog() {
-    final Slf4jRequestLog requestLog = new Slf4jRequestLog();
-    requestLog.setLoggerName(LOG.getName() + ".RequestLog");
-    requestLog.setExtended(true);
-    return requestLog;
+    Slf4jRequestLogWriter writer = new Slf4jRequestLogWriter();
+    writer.setLoggerName(LOG.getName() + ".RequestLog");
+    return new CustomRequestLog(writer, CustomRequestLog.EXTENDED_NCSA_FORMAT);
   }
 
-  private static class MockHandler extends AbstractHandler {
+  private static class MockHandler extends Handler.Abstract {
 
     private final ReadWriteLock responseMappingLock = new 
ReentrantReadWriteLock();
-    private final Map<String, BiConsumer<String, HttpServletResponse>> 
responseMapping =
-      new HashMap<>();
+    private final Map<String, BiConsumer<String, Response>> responseMapping = 
new HashMap<>();
     private final RegexSet regexSet = new RegexSet();
 
-    void register(final String pathRegex, final BiConsumer<String, 
HttpServletResponse> responder) {
+    void register(final String pathRegex, final BiConsumer<String, Response> 
responder) {
       LOG.debug("Registering responder to '{}'", pathRegex);
       responseMappingLock.writeLock().lock();
       try {
@@ -151,20 +157,25 @@ public class MockHttpApiRule extends ExternalResource {
     }
 
     @Override
-    public void handle(final String target, final Request baseRequest,
-      final HttpServletRequest request, final HttpServletResponse response) {
+    public boolean handle(Request request, Response response, Callback 
callback) throws Exception {
+      String target = request.getHttpURI().getPath();
       responseMappingLock.readLock().lock();
       try {
         if (!regexSet.matches(target)) {
           response.setStatus(HttpServletResponse.SC_NOT_FOUND);
-          return;
+          callback.succeeded();
+          return true;
         }
         responseMapping.entrySet().stream().filter(e -> 
Pattern.matches(e.getKey(), target))
           .findAny().map(Map.Entry::getValue).orElseThrow(() -> 
noMatchFound(target))
           .accept(target, response);
+        callback.succeeded();
+      } catch (Exception e) {
+        callback.failed(e);
       } finally {
         responseMappingLock.readLock().unlock();
       }
+      return true;
     }
 
     private static RuntimeException noMatchFound(final String target) {
diff --git 
a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java 
b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
index 760f2ca8b41..666c994d692 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
@@ -23,8 +23,10 @@ import java.lang.management.ManagementFactory;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ArrayBlockingQueue;
 import javax.servlet.DispatcherType;
 import org.apache.commons.lang3.ArrayUtils;
@@ -57,7 +59,11 @@ import 
org.apache.hbase.thirdparty.org.apache.commons.cli.HelpFormatter;
 import org.apache.hbase.thirdparty.org.apache.commons.cli.Options;
 import org.apache.hbase.thirdparty.org.apache.commons.cli.ParseException;
 import org.apache.hbase.thirdparty.org.apache.commons.cli.PosixParser;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.FilterHolder;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.ServletContextHandler;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.ServletHolder;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.http.HttpVersion;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.http.UriCompliance;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.jmx.MBeanContainer;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.HttpConfiguration;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.HttpConnectionFactory;
@@ -65,9 +71,6 @@ import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.SecureRequestCustomi
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.ServerConnector;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.SslConnectionFactory;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.FilterHolder;
-import 
org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletContextHandler;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHolder;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.util.ssl.SslContextFactory;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.util.thread.QueuedThreadPool;
 import org.apache.hbase.thirdparty.org.glassfish.jersey.server.ResourceConfig;
@@ -287,6 +290,13 @@ public class RESTServer implements Constants {
     httpConfig.setSendServerVersion(false);
     httpConfig.setSendDateHeader(false);
 
+    // In Jetty 12, ambiguous path separators, suspicious path characters, and 
ambiguous empty
+    // segments are considered violations of the URI specification and hence 
are not allowed.
+    // Refer to 
https://github.com/jetty/jetty.project/issues/11890#issuecomment-2156449534
+    // We must set a URI compliance to allow for this violation so that client 
requests are not
+    // automatically rejected. Our rest endpoints rely on this behavior to 
handle encoded uri paths.
+    setUriComplianceRules(httpConfig);
+
     ServerConnector serverConnector;
     boolean isSecure = false;
     if (conf.getBoolean(REST_SSL_ENABLED, false)) {
@@ -400,6 +410,14 @@ public class RESTServer implements Constants {
     server.start();
   }
 
+  private static void setUriComplianceRules(HttpConfiguration httpConfig) {
+    Set<UriCompliance.Violation> complianceViolationSet = new HashSet<>();
+    
complianceViolationSet.add(UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR);
+    
complianceViolationSet.add(UriCompliance.Violation.SUSPICIOUS_PATH_CHARACTERS);
+    
complianceViolationSet.add(UriCompliance.Violation.AMBIGUOUS_EMPTY_SEGMENT);
+    httpConfig.setUriCompliance(UriCompliance.from(complianceViolationSet));
+  }
+
   private static String getHostName(Configuration conf) throws 
UnknownHostException {
     return Strings.domainNamePointerToHostName(DNS.getDefaultHost(
       conf.get(REST_DNS_INTERFACE, "default"), conf.get(REST_DNS_NAMESERVER, 
"default")));
diff --git 
a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestGetAndPutResource.java
 
b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestGetAndPutResource.java
index b20baea9df8..21e948e3cfc 100644
--- 
a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestGetAndPutResource.java
+++ 
b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestGetAndPutResource.java
@@ -321,6 +321,11 @@ public class TestGetAndPutResource extends RowResourceBase 
{
 
   @Test
   public void testURLEncodedKey() throws IOException, JAXBException {
+    // Requires UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR
+    // Otherwise fails with "400: Ambiguous URI path separator"
+    // In this test, request url resolves to 
"/TestRowResource/http%3A%2F%2Fexample.com%2Ffoo/a:1"
+    // and is considered ambiguous by Jetty 12.
+    // Basically we are having a URL encoded string as row key here!
     String urlKey = "http://example.com/foo";;
     StringBuilder path = new StringBuilder();
     path.append('/');
diff --git 
a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteTable.java
 
b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteTable.java
index fcbe7c7ca02..c464a51813e 100644
--- 
a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteTable.java
+++ 
b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteTable.java
@@ -164,6 +164,12 @@ public class TestRemoteTable {
 
   @Test
   public void testGet() throws IOException {
+    // Requires UriCompliance.Violation.SUSPICIOUS_PATH_CHARACTERS
+    // Otherwise fails with "400: Suspicious Path Character"
+    // In this test, the request path resolves to
+    // 
"/TestRemoteTable_-./testrow1%7C%22%5C%5E%7B%7D%01%02%03%04%05%06%07%08%09%0B%0C/"
+    // and is considered suspicious by the Jetty 12.
+    // Basically ROW_1 contains invalid URL characters here.
     Get get = new Get(ROW_1);
     Result result = remoteTable.get(get);
     byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1);
@@ -264,6 +270,9 @@ public class TestRemoteTable {
 
   @Test
   public void testMultiGet() throws Exception {
+    // In case of multi gets, the request path resolves to
+    // 
"/TestRemoteTable_-./multiget/?row=testrow1%7C%22%5C%5E&row=testrow2%7C%22%5C%5E%&v=3"
+    // and hence is not considered suspicious by the Jetty 12.
     ArrayList<Get> gets = new ArrayList<>(2);
     gets.add(new Get(ROW_1));
     gets.add(new Get(ROW_2));
@@ -303,6 +312,8 @@ public class TestRemoteTable {
 
   @Test
   public void testPut() throws IOException {
+    // Requires UriCompliance.Violation.SUSPICIOUS_PATH_CHARACTERS
+    // Otherwise fails with "400: Suspicious Path Character"
     Put put = new Put(ROW_3);
     put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1);
     remoteTable.put(put);
@@ -348,6 +359,13 @@ public class TestRemoteTable {
 
   @Test
   public void testDelete() throws IOException {
+    // Requires UriCompliance.Violation.SUSPICIOUS_PATH_CHARACTERS for put,
+    // otherwise fails with "400: Suspicious Path Character"
+    // This example is considered suspicious by the Jetty 12 due to reasons 
same as shown in
+    // testGet()
+
+    // Also, requires UriCompliance.Violation.AMBIGUOUS_EMPTY_SEGMENT
+    // Otherwise fails with "400: Ambiguous URI empty segment"
     Put put = new Put(ROW_3);
     put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1);
     put.addColumn(COLUMN_2, QUALIFIER_2, VALUE_2);
@@ -387,6 +405,9 @@ public class TestRemoteTable {
     assertTrue(Bytes.equals(VALUE_1, value1));
     assertNull(value2);
 
+    // This leads to path which resolves to
+    // 
"/TestRemoteTable_-./testrow3%7C%22%5C%5E%7B%7D%01%02%03%04%05%06%07%08%09%0B%0C//1"
+    // causing "400: Ambiguous URI empty segment" error with Jetty 12.
     delete = new Delete(ROW_3);
     delete.setTimestamp(1L);
     remoteTable.delete(delete);
@@ -493,6 +514,10 @@ public class TestRemoteTable {
 
   @Test
   public void testCheckAndDelete() throws IOException {
+    // Requires UriCompliance.Violation.SUSPICIOUS_PATH_CHARACTERS
+    // Otherwise fails with "400: Suspicious Path Character"
+    // This example is considered suspicious by the Jetty 12 due to reasons 
same as shown in
+    // testGet()
     Get get = new Get(ROW_1);
     Result result = remoteTable.get(get);
     byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1);
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
index 19f58ebe6ad..317f571ba8a 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
@@ -287,10 +287,10 @@ import 
org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 import org.apache.hbase.thirdparty.com.google.gson.JsonParseException;
 import org.apache.hbase.thirdparty.com.google.protobuf.Descriptors;
 import org.apache.hbase.thirdparty.com.google.protobuf.Service;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.ServletHolder;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.webapp.WebAppContext;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.ServerConnector;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHolder;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.webapp.WebAppContext;
 import org.apache.hbase.thirdparty.org.glassfish.jersey.server.ResourceConfig;
 import 
org.apache.hbase.thirdparty.org.glassfish.jersey.servlet.ServletContainer;
 
diff --git 
a/hbase-shaded/hbase-shaded-check-invariants/src/test/resources/ensure-jars-have-correct-contents.sh
 
b/hbase-shaded/hbase-shaded-check-invariants/src/test/resources/ensure-jars-have-correct-contents.sh
index 1d1350712b1..8b63889f195 100644
--- 
a/hbase-shaded/hbase-shaded-check-invariants/src/test/resources/ensure-jars-have-correct-contents.sh
+++ 
b/hbase-shaded/hbase-shaded-check-invariants/src/test/resources/ensure-jars-have-correct-contents.sh
@@ -98,6 +98,8 @@ allowed_expr+="|^about.html$"
 allowed_expr+="|^jetty-dir.css$"
 # Coming from Guava, see 
https://github.com/google/guava/commit/2cc8c5eddb587db3ac12dacdd5563e79a4681ec4
 
allowed_expr+="|^org/jspecify/$|^org/jspecify/annotations/$|^org/jspecify/annotations/.*\.class$"
+# Required by jetty 12 on ee8
+allowed_expr="(|^javax/$)"
 
 if [ -n "${allow_hadoop}" ]; then
   #   * classes in packages that start with org.apache.hadoop, which by
diff --git 
a/hbase-shaded/hbase-shaded-testing-util/src/main/resources/org/apache/hadoop/hbase/shaded/org/eclipse/jetty/webapp/webdefault.xml
 
b/hbase-shaded/hbase-shaded-testing-util/src/main/resources/org/apache/hadoop/hbase/shaded/org/eclipse/jetty/webapp/webdefault.xml
deleted file mode 100644
index 8f10b517eb5..00000000000
--- 
a/hbase-shaded/hbase-shaded-testing-util/src/main/resources/org/apache/hadoop/hbase/shaded/org/eclipse/jetty/webapp/webdefault.xml
+++ /dev/null
@@ -1,550 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-Copyright (C) Jetty Authors
-
-Licensed 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.
--->
-
-<web-app
-   xmlns="http://xmlns.jcp.org/xml/ns/javaee";
-   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd";
-   metadata-complete="false"
-   version="3.1">
-
-  <!-- ===================================================================== 
-->
-  <!-- This file contains the default descriptor for web applications.       
-->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
-->
-  <!-- The intent of this descriptor is to include jetty specific or common  
-->
-  <!-- configuration for all webapps.   If a context has a webdefault.xml    
-->
-  <!-- descriptor, it is applied before the context's own web.xml file       
-->
-  <!--                                                                       
-->
-  <!-- A context may be assigned a default descriptor by calling             
-->
-  <!-- WebAppContext.setDefaultsDescriptor(String).                          
-->
-  <!--                                                                       
-->
-  <!-- This file is present in the jetty-webapp.jar, and is used as the      
-->
-  <!-- defaults descriptor if no other is explicitly set on a context.       
-->
-  <!--                                                                       
-->
-  <!-- A copy of this file is also placed into the $JETTY_HOME/etc dir of    
-->
-  <!-- the  distribution, and is referenced by some of the other xml files,  
-->
-  <!-- eg the jetty-deploy.xml file.                                         
-->
-  <!-- ===================================================================== 
-->
-
-  <description>
-    Default web.xml file.
-    This file is applied to a Web application before it's own WEB_INF/web.xml 
file
-  </description>
-
-  <!-- ==================================================================== -->
-  <!-- Removes static references to beans from javax.el.BeanELResolver to   -->
-  <!-- ensure webapp classloader can be released on undeploy                -->
-  <!-- ==================================================================== -->
-  <listener>
-   
<listener-class>org.apache.hadoop.hbase.shaded.org.eclipse.jetty.servlet.listener.ELContextCleaner</listener-class>
-  </listener>
-
-  <!-- ==================================================================== -->
-  <!-- Removes static cache of Methods from java.beans.Introspector to      -->
-  <!-- ensure webapp classloader can be released on undeploy                -->
-  <!-- ==================================================================== -->
-  <listener>
-   
<listener-class>org.apache.hadoop.hbase.shaded.org.eclipse.jetty.servlet.listener.IntrospectorCleaner</listener-class>
-  </listener>
-
-
-  <!-- ==================================================================== -->
-  <!-- Context params to control Session Cookies                            -->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
-  <!--
-    UNCOMMENT TO ACTIVATE
-    <context-param>
-      <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name>
-      <param-value>127.0.0.1</param-value>
-    </context-param>
-    <context-param>
-      <param-name>org.eclipse.jetty.servlet.SessionPath</param-name>
-      <param-value>/</param-value>
-    </context-param>
-    <context-param>
-      <param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
-      <param-value>-1</param-value>
-    </context-param>
-  -->
-
-  <!-- ==================================================================== -->
-  <!-- The default servlet.                                                 -->
-  <!-- This servlet, normally mapped to /, provides the handling for static -->
-  <!-- content, OPTIONS and TRACE methods for the context.                  -->
-  <!-- The following initParameters are supported:                          -->
-  <!--
- *  acceptRanges      If true, range requests and responses are
- *                    supported
- *
- *  dirAllowed        If true, directory listings are returned if no
- *                    welcome file is found. Else 403 Forbidden.
- *
- *  welcomeServlets   If true, attempt to dispatch to welcome files
- *                    that are servlets, but only after no matching static
- *                    resources could be found. If false, then a welcome
- *                    file must exist on disk. If "exact", then exact
- *                    servlet matches are supported without an existing file.
- *                    Default is true.
- *
- *                    This must be false if you want directory listings,
- *                    but have index.jsp in your welcome file list.
- *
- *  redirectWelcome   If true, welcome files are redirected rather than
- *                    forwarded to.
- *
- *  gzip              If set to true, then static content will be served as
- *                    gzip content encoded if a matching resource is
- *                    found ending with ".gz"
- *
- *  resourceBase      Set to replace the context resource base
- *
- *  resourceCache     If set, this is a context attribute name, which the 
servlet
- *                    will use to look for a shared ResourceCache instance.
- *
- *  relativeResourceBase
- *                    Set with a pathname relative to the base of the
- *                    servlet context root. Useful for only serving static 
content out
- *                    of only specific subdirectories.
- *
- *  pathInfoOnly      If true, only the path info will be applied to the 
resourceBase
- *
- *  stylesheet        Set with the location of an optional stylesheet that 
will be used
- *                    to decorate the directory listing html.
- *
- *  aliases           If True, aliases of resources are allowed (eg. symbolic
- *                    links and caps variations). May bypass security 
constraints.
- *
- *  etags             If True, weak etags will be generated and handled.
- *
- *  maxCacheSize      The maximum total size of the cache or 0 for no cache.
- *  maxCachedFileSize The maximum size of a file to cache
- *  maxCachedFiles    The maximum number of files to cache
- *
- *  useFileMappedBuffer
- *                    If set to true, it will use mapped file buffers to serve 
static content
- *                    when using an NIO connector. Setting this value to false 
means that
- *                    a direct buffer will be used instead of a mapped file 
buffer.
- *                    This file sets the value to true.
- *
- *  cacheControl      If set, all static content will have this value set as 
the cache-control
- *                    header.
- *
- -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
-  <servlet>
-    <servlet-name>default</servlet-name>
-    
<servlet-class>org.apache.hadoop.hbase.shaded.org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
-    <init-param>
-      <param-name>aliases</param-name>
-      <param-value>false</param-value>
-    </init-param>
-    <init-param>
-      <param-name>acceptRanges</param-name>
-      <param-value>true</param-value>
-    </init-param>
-    <init-param>
-      <param-name>dirAllowed</param-name>
-      <param-value>true</param-value>
-    </init-param>
-    <init-param>
-      <param-name>welcomeServlets</param-name>
-      <param-value>false</param-value>
-    </init-param>
-    <init-param>
-      <param-name>redirectWelcome</param-name>
-      <param-value>false</param-value>
-    </init-param>
-    <init-param>
-      <param-name>maxCacheSize</param-name>
-      <param-value>256000000</param-value>
-    </init-param>
-    <init-param>
-      <param-name>maxCachedFileSize</param-name>
-      <param-value>200000000</param-value>
-    </init-param>
-    <init-param>
-      <param-name>maxCachedFiles</param-name>
-      <param-value>2048</param-value>
-    </init-param>
-    <init-param>
-      <param-name>gzip</param-name>
-      <param-value>false</param-value>
-    </init-param>
-    <init-param>
-      <param-name>etags</param-name>
-      <param-value>false</param-value>
-    </init-param>
-    <init-param>
-      <param-name>useFileMappedBuffer</param-name>
-      <param-value>true</param-value>
-    </init-param>
-    <!--
-    <init-param>
-      <param-name>resourceCache</param-name>
-      <param-value>resourceCache</param-value>
-    </init-param>
-    -->
-    <!--
-    <init-param>
-      <param-name>cacheControl</param-name>
-      <param-value>max-age=3600,public</param-value>
-    </init-param>
-    -->
-    <load-on-startup>0</load-on-startup>
-  </servlet>
-
-  <servlet-mapping>
-    <servlet-name>default</servlet-name>
-    <url-pattern>/</url-pattern>
-  </servlet-mapping>
-
-
-  <!-- ==================================================================== -->
-  <!-- JSP Servlet                                                          -->
-  <!-- This is the jasper JSP servlet.                                      -->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
-  <!-- The JSP page compiler and execution servlet, which is the mechanism  -->
-  <!-- used by the jsp container to support JSP pages.  Traditionally,      -->
-  <!-- this servlet is mapped to URL pattern "*.jsp".  This servlet         -->
-  <!-- supports the following initialization parameters (default values     -->
-  <!-- are in square brackets):                                             -->
-  <!--                                                                      -->
-  <!--   checkInterval       If development is false and reloading is true, -->
-  <!--                       background compiles are enabled. checkInterval -->
-  <!--                       is the time in seconds between checks to see   -->
-  <!--                       if a JSP page needs to be recompiled. [300]    -->
-  <!--                                                                      -->
-  <!--   compiler            Which compiler Ant should use to compile JSP   -->
-  <!--                       pages.  See the Ant documentation for more     -->
-  <!--                       information. [javac]                           -->
-  <!--                                                                      -->
-  <!--   classdebuginfo      Should the class file be compiled with         -->
-  <!--                       debugging information?  [true]                 -->
-  <!--                                                                      -->
-  <!--   classpath           What class path should I use while compiling   -->
-  <!--                       generated servlets?  [Created dynamically      -->
-  <!--                       based on the current web application]          -->
-  <!--                       Set to ? to make the container explicitly set  -->
-  <!--                       this parameter.                                -->
-  <!--                                                                      -->
-  <!--   development         Is Jasper used in development mode (will check -->
-  <!--                       for JSP modification on every access)?  [true] -->
-  <!--                                                                      -->
-  <!--   enablePooling       Determines whether tag handler pooling is      -->
-  <!--                       enabled  [true]                                -->
-  <!--                                                                      -->
-  <!--   fork                Tell Ant to fork compiles of JSP pages so that -->
-  <!--                       a separate JVM is used for JSP page compiles   -->
-  <!--                       from the one Tomcat is running in. [true]      -->
-  <!--                                                                      -->
-  <!--   ieClassId           The class-id value to be sent to Internet      -->
-  <!--                       Explorer when using <jsp:plugin> tags.         -->
-  <!--                       [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93]   -->
-  <!--                                                                      -->
-  <!--   javaEncoding        Java file encoding to use for generating java  -->
-  <!--                       source files. [UTF-8]                          -->
-  <!--                                                                      -->
-  <!--   keepgenerated       Should we keep the generated Java source code  -->
-  <!--                       for each page instead of deleting it? [true]   -->
-  <!--                                                                      -->
-  <!--   logVerbosityLevel   The level of detailed messages to be produced  -->
-  <!--                       by this servlet.  Increasing levels cause the  -->
-  <!--                       generation of more messages.  Valid values are -->
-  <!--                       FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
-  <!--                       [WARNING]                                      -->
-  <!--                                                                      -->
-  <!--   mappedfile          Should we generate static content with one     -->
-  <!--                       print statement per input line, to ease        -->
-  <!--                       debugging?  [false]                            -->
-  <!--                                                                      -->
-  <!--                                                                      -->
-  <!--   reloading           Should Jasper check for modified JSPs?  [true] -->
-  <!--                                                                      -->
-  <!--   suppressSmap        Should the generation of SMAP info for JSR45   -->
-  <!--                       debugging be suppressed?  [false]              -->
-  <!--                                                                      -->
-  <!--   dumpSmap            Should the SMAP info for JSR45 debugging be    -->
-  <!--                       dumped to a file? [false]                      -->
-  <!--                       False if suppressSmap is true                  -->
-  <!--                                                                      -->
-  <!--   scratchdir          What scratch directory should we use when      -->
-  <!--                       compiling JSP pages?  [default work directory  -->
-  <!--                       for the current web application]               -->
-  <!--                                                                      -->
-  <!--   tagpoolMaxSize      The maximum tag handler pool size  [5]         -->
-  <!--                                                                      -->
-  <!--   xpoweredBy          Determines whether X-Powered-By response       -->
-  <!--                       header is added by generated servlet  [false]  -->
-  <!--                                                                      -->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
-  <servlet id="jsp">
-    <servlet-name>jsp</servlet-name>
-    
<servlet-class>org.apache.hadoop.hbase.shaded.org.eclipse.jetty.jsp.JettyJspServlet</servlet-class>
-    <init-param>
-      <param-name>logVerbosityLevel</param-name>
-      <param-value>DEBUG</param-value>
-    </init-param>
-    <init-param>
-      <param-name>fork</param-name>
-      <param-value>false</param-value>
-    </init-param>
-    <init-param>
-      <param-name>xpoweredBy</param-name>
-      <param-value>false</param-value>
-    </init-param>
-    <init-param>
-      <param-name>compilerTargetVM</param-name>
-      <param-value>1.7</param-value>
-    </init-param>
-    <init-param>
-      <param-name>compilerSourceVM</param-name>
-      <param-value>1.7</param-value>
-    </init-param>
-    <!--
-    <init-param>
-        <param-name>classpath</param-name>
-        <param-value>?</param-value>
-    </init-param>
-    -->
-    <load-on-startup>0</load-on-startup>
-  </servlet>
-
-  <servlet-mapping>
-    <servlet-name>jsp</servlet-name>
-    <url-pattern>*.jsp</url-pattern>
-    <url-pattern>*.jspf</url-pattern>
-    <url-pattern>*.jspx</url-pattern>
-    <url-pattern>*.xsp</url-pattern>
-    <url-pattern>*.JSP</url-pattern>
-    <url-pattern>*.JSPF</url-pattern>
-    <url-pattern>*.JSPX</url-pattern>
-    <url-pattern>*.XSP</url-pattern>
-  </servlet-mapping>
-
-
-  <!-- ==================================================================== -->
-  <!-- Default session configuration                                        -->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
-  <session-config>
-    <session-timeout>30</session-timeout>
-  </session-config>
-
-  <!-- ==================================================================== -->
-  <!-- Default MIME mappings                                                -->
-  <!-- The default MIME mappings are provided by the mime.properties        -->
-  <!-- resource in the jetty-http.jar file.  Additional or modified         -->
-  <!-- mappings may be specified here                                       -->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
-  <!-- UNCOMMENT TO ACTIVATE
-  <mime-mapping>
-    <extension>mysuffix</extension>
-    <mime-type>mymime/type</mime-type>
-  </mime-mapping>
-  -->
-
-  <!-- ==================================================================== -->
-  <!-- Default welcome files                                                -->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
-  <welcome-file-list>
-    <welcome-file>index.html</welcome-file>
-    <welcome-file>index.htm</welcome-file>
-    <welcome-file>index.jsp</welcome-file>
-  </welcome-file-list>
-
-  <!-- ==================================================================== -->
-  <!-- Default locale encodings                                             -->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
-  <locale-encoding-mapping-list>
-    <locale-encoding-mapping>
-      <locale>ar</locale>
-      <encoding>ISO-8859-6</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>be</locale>
-      <encoding>ISO-8859-5</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>bg</locale>
-      <encoding>ISO-8859-5</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>ca</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>cs</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>da</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>de</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>el</locale>
-      <encoding>ISO-8859-7</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>en</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>es</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>et</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>fi</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>fr</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>hr</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>hu</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>is</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>it</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>iw</locale>
-      <encoding>ISO-8859-8</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>ja</locale>
-      <encoding>Shift_JIS</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>ko</locale>
-      <encoding>EUC-KR</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>lt</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>lv</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>mk</locale>
-      <encoding>ISO-8859-5</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>nl</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>no</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>pl</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>pt</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>ro</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>ru</locale>
-      <encoding>ISO-8859-5</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>sh</locale>
-      <encoding>ISO-8859-5</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>sk</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>sl</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>sq</locale>
-      <encoding>ISO-8859-2</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>sr</locale>
-      <encoding>ISO-8859-5</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>sv</locale>
-      <encoding>ISO-8859-1</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>tr</locale>
-      <encoding>ISO-8859-9</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>uk</locale>
-      <encoding>ISO-8859-5</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>zh</locale>
-      <encoding>GB2312</encoding>
-    </locale-encoding-mapping>
-    <locale-encoding-mapping>
-      <locale>zh_TW</locale>
-      <encoding>Big5</encoding>
-    </locale-encoding-mapping>
-  </locale-encoding-mapping-list>
-
-  <!-- ==================================================================== -->
-  <!-- Disable TRACE method with security constraint                        -->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
-  <security-constraint>
-    <web-resource-collection>
-      <web-resource-name>Disable TRACE</web-resource-name>
-      <url-pattern>/</url-pattern>
-      <http-method>TRACE</http-method>
-    </web-resource-collection>
-    <auth-constraint/>
-  </security-constraint>
-  <security-constraint>
-    <web-resource-collection>
-      <web-resource-name>Enable everything but TRACE</web-resource-name>
-      <url-pattern>/</url-pattern>
-      <http-method-omission>TRACE</http-method-omission>
-    </web-resource-collection>
-  </security-constraint>
-
-</web-app>
diff --git 
a/hbase-shaded/hbase-shaded-with-hadoop-check-invariants/src/test/resources/ensure-jars-have-correct-contents.sh
 
b/hbase-shaded/hbase-shaded-with-hadoop-check-invariants/src/test/resources/ensure-jars-have-correct-contents.sh
index 1d1350712b1..8b63889f195 100644
--- 
a/hbase-shaded/hbase-shaded-with-hadoop-check-invariants/src/test/resources/ensure-jars-have-correct-contents.sh
+++ 
b/hbase-shaded/hbase-shaded-with-hadoop-check-invariants/src/test/resources/ensure-jars-have-correct-contents.sh
@@ -98,6 +98,8 @@ allowed_expr+="|^about.html$"
 allowed_expr+="|^jetty-dir.css$"
 # Coming from Guava, see 
https://github.com/google/guava/commit/2cc8c5eddb587db3ac12dacdd5563e79a4681ec4
 
allowed_expr+="|^org/jspecify/$|^org/jspecify/annotations/$|^org/jspecify/annotations/.*\.class$"
+# Required by jetty 12 on ee8
+allowed_expr="(|^javax/$)"
 
 if [ -n "${allow_hadoop}" ]; then
   #   * classes in packages that start with org.apache.hadoop, which by
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServer.java 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServer.java
index 7f2d3744029..a0370aab0fb 100644
--- 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServer.java
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServer.java
@@ -144,6 +144,8 @@ import 
org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLineParser;
 import org.apache.hbase.thirdparty.org.apache.commons.cli.DefaultParser;
 import org.apache.hbase.thirdparty.org.apache.commons.cli.HelpFormatter;
 import org.apache.hbase.thirdparty.org.apache.commons.cli.Options;
+import 
org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.ServletContextHandler;
+import org.apache.hbase.thirdparty.org.eclipse.jetty.ee8.servlet.ServletHolder;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.http.HttpVersion;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.HttpConfiguration;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.HttpConnectionFactory;
@@ -151,8 +153,6 @@ import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.SecureRequestCustomi
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server;
 import org.apache.hbase.thirdparty.org.eclipse.jetty.server.ServerConnector;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.server.SslConnectionFactory;
-import 
org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletContextHandler;
-import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHolder;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.util.ssl.SslContextFactory;
 import 
org.apache.hbase.thirdparty.org.eclipse.jetty.util.thread.QueuedThreadPool;
 
diff --git a/pom.xml b/pom.xml
index 30c63fca381..bb24fe435cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -893,9 +893,9 @@
     <jackson.version>2.19.2</jackson.version>
     <jackson.databind.version>2.19.2</jackson.databind.version>
     <jaxb-api.version>2.3.1</jaxb-api.version>
-    <servlet.api.version>3.1.0</servlet.api.version>
+    <servlet.api.version>4.0.1</servlet.api.version>
     <wx.rs.api.version>2.1.1</wx.rs.api.version>
-    <tomcat.jasper.version>9.0.104</tomcat.jasper.version>
+    <tomcat.jasper.version>9.0.108</tomcat.jasper.version>
     <jruby.version>9.4.12.1</jruby.version>
     <junit.version>4.13.2</junit.version>
     <hamcrest.version>1.3</hamcrest.version>
@@ -975,7 +975,7 @@
     <!-- for.exclusion version are NOT for direct dependencies. To use the 
provided
     scope to transitively exclude some transitive dependencies, we need to 
specify
     some existing version to for maven. -->
-    <tomcat.version.for.exclusion>9.0.93</tomcat.version.for.exclusion>
+    
<tomcat.version.for.exclusion>${tomcat.jasper.version}</tomcat.version.for.exclusion>
     <!-- Coverage properties -->
     <jacoco.version>0.8.8</jacoco.version>
     <jacocoArgLine/>
@@ -1847,7 +1847,12 @@
       </dependency>
       <dependency>
         <groupId>org.apache.hbase.thirdparty</groupId>
-        <artifactId>hbase-shaded-jetty</artifactId>
+        <artifactId>hbase-shaded-jetty-12-plus-core</artifactId>
+        <version>${hbase-thirdparty.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hbase.thirdparty</groupId>
+        <artifactId>hbase-shaded-jetty-12-plus-ee8</artifactId>
         <version>${hbase-thirdparty.version}</version>
       </dependency>
       <dependency>

Reply via email to