diff --git a/.gitignore b/.gitignore
index f4b640b..53cd238 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,8 @@
**/dependency-reduced-pom.xml
hbase-shaded-protobuf/src/main/java
hbase-shaded-protobuf/src/main/resources
+hbase-shaded-thrift/src/main/java
+hbase-shaded-thrift/src/main/resources
.project
.settings
.classpath
diff --git a/hbase-shaded-thrift/pom.xml b/hbase-shaded-thrift/pom.xml
new file mode 100644
index 0000000..521904e
--- /dev/null
+++ b/hbase-shaded-thrift/pom.xml
@@ -0,0 +1,227 @@
+
+
+
+ 4.0.0
+
+ org.apache.hbase.thirdparty
+ hbase-thirdparty
+ ${revision}
+ ..
+
+ hbase-shaded-thrift
+ Apache HBase Patched and Relocated (Shaded) Thrift
+ Pulls down libthrift, patches it, compiles, and then relocates/shades.
+
+
+ ${hbase.unsafe.and.protobuf.java.version}
+ ${java.release.version}
+ ${java.release.version}
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+ provided
+
+
+ javax.servlet
+ javax.servlet-api
+ ${servlet-api.version}
+ provided
+
+
+ org.apache.httpcomponents
+ httpclient
+ ${httpclient.version}
+ provided
+
+
+ org.apache.httpcomponents
+ httpcore
+ ${httpcore.version}
+ provided
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+ provided
+
+
+
+
+
+
+ maven-clean-plugin
+
+
+
+ ${basedir}/src/main/java
+
+ **/**
+
+ false
+
+
+ ${basedir}/src/main/resources
+
+ **/**
+
+ false
+
+
+
+
+
+ pre-generate-sources
+
+ clean
+
+ generate-sources
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ unpack
+
+ unpack
+
+ generate-sources
+
+
+
+
+ org.apache.thrift
+ libthrift
+ ${thrift.version}
+ sources
+ jar
+ true
+ ${basedir}/src/main/java
+ **/**
+
+
+
+ org.apache.thrift
+ libthrift
+ ${thrift.version}
+ jar
+ true
+ ${basedir}/src/main/resources
+ META-INF/LICENSE.txt,META-INF/NOTICE.txt
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-patch-plugin
+
+ ${basedir}
+ false
+
+
+
+ patch
+
+ apply
+
+ process-sources
+
+ 1
+ ${basedir}/src/main/patches
+ ${project.build.directory}/patches-applied.txt
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+
+
+
+ shade
+
+ package
+
+ true
+ true
+
+
+ org.apache.thrift
+ ${rename.offset}.org.apache.thrift
+
+
+
+
+
+
+
+
+
diff --git a/hbase-shaded-thrift/src/main/appended-resources/META-INF/LICENSE b/hbase-shaded-thrift/src/main/appended-resources/META-INF/LICENSE
new file mode 100644
index 0000000..8c1cee5
--- /dev/null
+++ b/hbase-shaded-thrift/src/main/appended-resources/META-INF/LICENSE
@@ -0,0 +1,19 @@
+
+---
+
+This project incorporates portions of the 'Apache Thrift' project (libthrift),
+which is published under the Apache License, Version 2.0.
+
+ Copyright (C) 2006 - 2024, The Apache Software Foundation
+
+ 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.
diff --git a/hbase-shaded-thrift/src/main/appended-resources/META-INF/NOTICE b/hbase-shaded-thrift/src/main/appended-resources/META-INF/NOTICE
new file mode 100644
index 0000000..11ae5f0
--- /dev/null
+++ b/hbase-shaded-thrift/src/main/appended-resources/META-INF/NOTICE
@@ -0,0 +1,8 @@
+
+---
+
+Apache Thrift
+Copyright (C) 2006 - 2024, The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/hbase-shaded-thrift/src/main/patches/HBASE-30194-01-servlet-javax.patch b/hbase-shaded-thrift/src/main/patches/HBASE-30194-01-servlet-javax.patch
new file mode 100644
index 0000000..16e0be7
--- /dev/null
+++ b/hbase-shaded-thrift/src/main/patches/HBASE-30194-01-servlet-javax.patch
@@ -0,0 +1,39 @@
+diff --git a/src/main/java/org/apache/thrift/server/TServlet.java b/src/main/java/org/apache/thrift/server/TServlet.java
+--- a/src/main/java/org/apache/thrift/server/TServlet.java
++++ b/src/main/java/org/apache/thrift/server/TServlet.java
+@@ -1,9 +1,9 @@
+ package org.apache.thrift.server;
+
+-import jakarta.servlet.ServletException;
+-import jakarta.servlet.http.HttpServlet;
+-import jakarta.servlet.http.HttpServletRequest;
+-import jakarta.servlet.http.HttpServletResponse;
++import javax.servlet.ServletException;
++import javax.servlet.http.HttpServlet;
++import javax.servlet.http.HttpServletRequest;
++import javax.servlet.http.HttpServletResponse;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.OutputStream;
+diff --git a/src/main/java/org/apache/thrift/server/TExtensibleServlet.java b/src/main/java/org/apache/thrift/server/TExtensibleServlet.java
+--- a/src/main/java/org/apache/thrift/server/TExtensibleServlet.java
++++ b/src/main/java/org/apache/thrift/server/TExtensibleServlet.java
+@@ -19,12 +19,12 @@
+
+ package org.apache.thrift.server;
+
+-import jakarta.servlet.ServletConfig;
+-import jakarta.servlet.ServletContext;
+-import jakarta.servlet.ServletException;
+-import jakarta.servlet.http.HttpServlet;
+-import jakarta.servlet.http.HttpServletRequest;
+-import jakarta.servlet.http.HttpServletResponse;
++import javax.servlet.ServletConfig;
++import javax.servlet.ServletContext;
++import javax.servlet.ServletException;
++import javax.servlet.http.HttpServlet;
++import javax.servlet.http.HttpServletRequest;
++import javax.servlet.http.HttpServletResponse;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.OutputStream;
diff --git a/hbase-shaded-thrift/src/main/patches/HBASE-30194-02-httpclient4.patch b/hbase-shaded-thrift/src/main/patches/HBASE-30194-02-httpclient4.patch
new file mode 100644
index 0000000..e76ac3e
--- /dev/null
+++ b/hbase-shaded-thrift/src/main/patches/HBASE-30194-02-httpclient4.patch
@@ -0,0 +1,129 @@
+diff --git a/src/main/java/org/apache/thrift/THttpClientResponseHandler.java b/src/main/java/org/apache/thrift/THttpClientResponseHandler.java
+--- a/src/main/java/org/apache/thrift/THttpClientResponseHandler.java
++++ b/src/main/java/org/apache/thrift/THttpClientResponseHandler.java
+@@ -4,18 +4,18 @@
+ import java.io.ByteArrayOutputStream;
+ import java.io.IOException;
+ import java.io.InputStream;
+-import org.apache.hc.core5.http.ClassicHttpResponse;
+-import org.apache.hc.core5.http.HttpEntity;
+-import org.apache.hc.core5.http.HttpException;
+-import org.apache.hc.core5.http.HttpStatus;
+-import org.apache.hc.core5.http.io.HttpClientResponseHandler;
++import org.apache.http.HttpEntity;
++import org.apache.http.HttpResponse;
++import org.apache.http.HttpStatus;
++import org.apache.http.client.ResponseHandler;
++import org.apache.http.client.ClientProtocolException;
+
+-public class THttpClientResponseHandler implements HttpClientResponseHandler {
++public class THttpClientResponseHandler implements ResponseHandler {
+ @Override
+- public InputStream handleResponse(ClassicHttpResponse response)
+- throws HttpException, IOException {
++ public InputStream handleResponse(HttpResponse response)
++ throws ClientProtocolException, IOException {
+ try (InputStream is = response.getEntity().getContent()) {
+- int responseCode = response.getCode();
++ int responseCode = response.getStatusLine().getStatusCode();
+ if (responseCode != HttpStatus.SC_OK) {
+ throw new IOException("HTTP Response code: " + responseCode);
+ }
+diff --git a/src/main/java/org/apache/thrift/transport/THttpClient.java b/src/main/java/org/apache/thrift/transport/THttpClient.java
+--- a/src/main/java/org/apache/thrift/transport/THttpClient.java
++++ b/src/main/java/org/apache/thrift/transport/THttpClient.java
+@@ -27,13 +27,11 @@
+ import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.Map;
+-import org.apache.hc.client5.http.classic.HttpClient;
+-import org.apache.hc.client5.http.classic.methods.HttpPost;
+-import org.apache.hc.client5.http.config.ConnectionConfig;
+-import org.apache.hc.client5.http.config.RequestConfig;
+-import org.apache.hc.core5.http.HttpHost;
+-import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
+-import org.apache.hc.core5.util.Timeout;
++import org.apache.http.HttpHost;
++import org.apache.http.client.HttpClient;
++import org.apache.http.client.config.RequestConfig;
++import org.apache.http.client.methods.HttpPost;
++import org.apache.http.entity.ByteArrayEntity;
+ import org.apache.thrift.TConfiguration;
+ import org.apache.thrift.THttpClientResponseHandler;
+
+@@ -138,9 +136,9 @@
+ this.client = client;
+ this.host =
+ new HttpHost(
+- url_.getProtocol(),
+ url_.getHost(),
+- -1 == url_.getPort() ? url_.getDefaultPort() : url_.getPort());
++ -1 == url_.getPort() ? url_.getDefaultPort() : url_.getPort(),
++ url_.getProtocol());
+ } catch (IOException iox) {
+ throw new TTransportException(iox);
+ }
+@@ -153,9 +151,9 @@
+ this.client = client;
+ this.host =
+ new HttpHost(
+- url_.getProtocol(),
+ url_.getHost(),
+- -1 == url_.getPort() ? url_.getDefaultPort() : url_.getPort());
++ -1 == url_.getPort() ? url_.getDefaultPort() : url_.getPort(),
++ url_.getProtocol());
+ } catch (IOException iox) {
+ throw new TTransportException(iox);
+ }
+@@ -166,10 +164,8 @@
+ }
+
+ /**
+- * Use instead {@link
+- * org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager#setConnectionConfig} or
+- * {@link
+- * org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager#setDefaultConnectionConfig}
++ * Use instead a {@link RequestConfig} pre-configured on the underlying Apache HttpClient (e.g.
++ * via {@code HttpClientBuilder#setDefaultRequestConfig}).
+ */
+ @Deprecated
+ public void setReadTimeout(int timeout) {
+@@ -233,25 +229,14 @@
+ }
+
+ private RequestConfig getRequestConfig() {
+- RequestConfig requestConfig = RequestConfig.DEFAULT;
++ RequestConfig.Builder builder = RequestConfig.custom();
+ if (connectTimeout_ > 0) {
+- requestConfig =
+- RequestConfig.copy(requestConfig)
+- .setConnectionRequestTimeout(Timeout.ofMilliseconds(connectTimeout_))
+- .build();
++ builder.setConnectTimeout(connectTimeout_).setConnectionRequestTimeout(connectTimeout_);
+ }
+- return requestConfig;
+- }
+-
+- private ConnectionConfig getConnectionConfig() {
+- ConnectionConfig connectionConfig = ConnectionConfig.DEFAULT;
+ if (readTimeout_ > 0) {
+- connectionConfig =
+- ConnectionConfig.copy(connectionConfig)
+- .setSocketTimeout(Timeout.ofMilliseconds(readTimeout_))
+- .build();
++ builder.setSocketTimeout(readTimeout_);
+ }
+- return connectionConfig;
++ return builder.build();
+ }
+
+ private static Map getDefaultHeaders() {
+@@ -279,7 +264,7 @@
+ if (null != customHeaders_) {
+ customHeaders_.forEach(post::addHeader);
+ }
+- post.setEntity(new ByteArrayEntity(data, null));
++ post.setEntity(new ByteArrayEntity(data));
+ inputStream_ = client.execute(this.host, post, new THttpClientResponseHandler());
+ } catch (IOException ioe) {
+ // Abort method so the connection gets released back to the connection manager
diff --git a/pom.xml b/pom.xml
index 5b2d441..cdd517c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -95,6 +95,7 @@
hbase-shaded-protobuf
+ hbase-shaded-thrift
hbase-shaded-netty
hbase-shaded-netty-tcnative
hbase-shaded-gson
@@ -137,6 +138,10 @@
1.7.1
org.apache.hbase.thirdparty
4.34.0
+
+ 0.23.0
4.1.131.Final
2.0.75.Final
33.4.8-jre
@@ -155,6 +160,15 @@
3.30.2-GA
2.21.1
2.30.0
+
+ 1.7.36
+ 4.5.13
+ 4.4.13
+ 3.12.0
-Dorg.apache.hbase.thirdparty.io.netty.tryReflectionSetAccessible=true
@@ -245,6 +259,10 @@
**/src/main/java/com/google/protobuf/**
**/src/main/resources/google/**
**/src/main/java/META-INF/**
+
+ **/hbase-shaded-thrift/src/main/java/org/apache/thrift/**
+ **/hbase-shaded-thrift/src/main/resources/META-INF/LICENSE.txt
+ **/hbase-shaded-thrift/src/main/resources/META-INF/NOTICE.txt