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

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


The following commit(s) were added to refs/heads/master by this push:
     new 3316313  HBASE-30194 [thirdparty] Onboard libthrift to 
hbase-thirdparty (#160)
3316313 is described below

commit 33163133229810ad24c60a8ba396688e07b8eea3
Author: Andrew Purtell <[email protected]>
AuthorDate: Mon Jun 8 11:44:09 2026 -0700

    HBASE-30194 [thirdparty] Onboard libthrift to hbase-thirdparty (#160)
    
    Signed-off-by: Dávid Paksy <[email protected]>
    Signed-off-by: Duo Zhang <[email protected]>
    Signed-off-by: Nick Dimiduk <[email protected]>
    Signed-off-by: Nihal Jain <[email protected]>
    Co-Authored-by: Claude Opus 4.8[1m] <[email protected]>
---
 .gitignore                                         |   2 +
 hbase-shaded-thrift/pom.xml                        | 227 +++++++++++++++++++++
 .../src/main/appended-resources/META-INF/LICENSE   |  19 ++
 .../src/main/appended-resources/META-INF/NOTICE    |   8 +
 .../patches/HBASE-30194-01-servlet-javax.patch     |  39 ++++
 .../main/patches/HBASE-30194-02-httpclient4.patch  | 129 ++++++++++++
 pom.xml                                            |  19 ++
 7 files changed, 443 insertions(+)

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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+  <!--
+/**
+ * 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.
+ */
+-->
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.hbase.thirdparty</groupId>
+    <artifactId>hbase-thirdparty</artifactId>
+    <version>${revision}</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>hbase-shaded-thrift</artifactId>
+  <name>Apache HBase Patched and Relocated (Shaded) Thrift</name>
+  <description>Pulls down libthrift, patches it, compiles, and then 
relocates/shades.</description>
+  <properties>
+    <!-- Override parent's JDK 17 settings to force JDK 8 for 
hbase-shaded-thrift, matching the
+    other source-distribution shaded modules in this project (e.g. 
hbase-shaded-protobuf). The
+    patches we apply put libthrift back on the javax.servlet and Apache 
HttpClient 4.x surface,
+    which are Java 8 friendly. -->
+    
<toolchain.jdk.version>${hbase.unsafe.and.protobuf.java.version}</toolchain.jdk.version>
+    <maven.compiler.source>${java.release.version}</maven.compiler.source>
+    <maven.compiler.target>${java.release.version}</maven.compiler.target>
+  </properties>
+  <!--
+    The patched libthrift sources reference slf4j-api, javax.servlet-api, 
Apache HttpClient/Core
+    4.x, and commons-lang3 at compile time. These are NOT shaded; downstream 
consumers must
+    provide their own runtime versions (hbase-thrift already does). We declare 
them as provided
+    scope so they participate in compilation but never get bundled into the 
shaded jar. All
+    versions come from properties in the parent pom so they stay aligned with 
what the rest of
+    HBase expects at runtime.
+  -->
+  <dependencies>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <version>${servlet-api.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+      <version>${httpclient.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpcore</artifactId>
+      <version>${httpcore.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <version>${commons-lang3.version}</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <!-- Clean needs to purge src/main/java since this is where we overlay 
the unpack of
+             libthrift. Do it for usual clean goal but also before we unpack 
in case patches
+             delete/add files. We use src/main/java instead of dir under 
'target' because the
+             jar plugin is dumb, hard to make it source from other then 
src/main/java. -->
+        <artifactId>maven-clean-plugin</artifactId>
+        <configuration>
+          <filesets>
+            <fileset>
+              <directory>${basedir}/src/main/java</directory>
+              <includes>
+                <include>**/**</include>
+              </includes>
+              <followSymlinks>false</followSymlinks>
+            </fileset>
+            <fileset>
+              <directory>${basedir}/src/main/resources</directory>
+              <includes>
+                <include>**/**</include>
+              </includes>
+              <followSymlinks>false</followSymlinks>
+            </fileset>
+          </filesets>
+        </configuration>
+        <executions>
+          <execution>
+            <id>pre-generate-sources</id>
+            <goals>
+              <goal>clean</goal>
+            </goals>
+            <phase>generate-sources</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <!--Download our dependency src, i.e. libthrift, and
+             unpack it. Overlays src/main/java so ready for
+            compile-time (the jar plugin expects src in
+            src/main/java)-->
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <phase>generate-sources</phase>
+            <configuration>
+              <!--
+                The libthrift compile dependencies (slf4j, javax.servlet, 
httpclient, ...) are
+                declared as provided above, not here. We only unpack the 
source jar here.
+              -->
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.apache.thrift</groupId>
+                  <artifactId>libthrift</artifactId>
+                  <version>${thrift.version}</version>
+                  <classifier>sources</classifier>
+                  <type>jar</type>
+                  <overWrite>true</overWrite>
+                  <outputDirectory>${basedir}/src/main/java</outputDirectory>
+                  <includes>**/**</includes>
+                </artifactItem>
+                <!-- for the bundled LICENSE.txt / NOTICE.txt of libthrift -->
+                <artifactItem>
+                  <groupId>org.apache.thrift</groupId>
+                  <artifactId>libthrift</artifactId>
+                  <version>${thrift.version}</version>
+                  <type>jar</type>
+                  <overWrite>true</overWrite>
+                  
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
+                  <includes>META-INF/LICENSE.txt,META-INF/NOTICE.txt</includes>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+      </plugin>
+      <!--Apply our patches to the unpacked libthrift src-->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-patch-plugin</artifactId>
+        <configuration>
+          <targetDirectory>${basedir}</targetDirectory>
+          <skipApplication>false</skipApplication>
+        </configuration>
+        <executions>
+          <execution>
+            <id>patch</id>
+            <goals>
+              <goal>apply</goal>
+            </goals>
+            <phase>process-sources</phase>
+            <configuration>
+              <strip>1</strip>
+              <patchDirectory>${basedir}/src/main/patches</patchDirectory>
+              
<patchTrackingFile>${project.build.directory}/patches-applied.txt</patchTrackingFile>
+              <naturalOrderProcessing>true</naturalOrderProcessing>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <goals>
+              <goal>jar-no-fork</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <!--Above we built a jar. Now at package step, do relocation/shade-->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <shadeSourcesContent>true</shadeSourcesContent>
+              <createSourcesJar>true</createSourcesJar>
+              <relocations>
+                <relocation>
+                  <pattern>org.apache.thrift</pattern>
+                  
<shadedPattern>${rename.offset}.org.apache.thrift</shadedPattern>
+                </relocation>
+              </relocations>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
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<InputStream> {
++public class THttpClientResponseHandler implements 
ResponseHandler<InputStream> {
+   @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<String, String> 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..2118ea2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -95,6 +95,7 @@
   </mailingLists>
   <modules>
     <module>hbase-shaded-protobuf</module>
+    <module>hbase-shaded-thrift</module>
     <module>hbase-shaded-netty</module>
     <module>hbase-shaded-netty-tcnative</module>
     <module>hbase-shaded-gson</module>
@@ -137,6 +138,10 @@
     <os.maven.version>1.7.1</os.maven.version>
     <rename.offset>org.apache.hbase.thirdparty</rename.offset>
     <protobuf.version>4.34.0</protobuf.version>
+    <!-- libthrift sources jar pulled, patched, and shaded by 
hbase-shaded-thrift. The patches
+    under hbase-shaded-thrift/src/main/patches were authored against this 
exact version and will
+    not apply cleanly against any other. -->
+    <thrift.version>0.23.0</thrift.version>
     <netty.version>4.1.131.Final</netty.version>
     <netty.tcnative.version>2.0.75.Final</netty.tcnative.version>
     <guava.version>33.4.8-jre</guava.version>
@@ -155,6 +160,15 @@
     <javassist.version>3.30.2-GA</javassist.version>
     
<jackson-jaxrs-json-provider.version>2.21.1</jackson-jaxrs-json-provider.version>
     <spotless.version>2.30.0</spotless.version>
+    <!--
+      Compile-time deps used by the patched libthrift sources in 
hbase-shaded-thrift. The
+      shaded thrift jar does NOT bundle these. We set them at 'provided' scope 
at compile
+      time and downstream consumers supply them.
+    -->
+    <slf4j.version>1.7.36</slf4j.version>
+    <httpclient.version>4.5.13</httpclient.version>
+    <httpcore.version>4.4.13</httpcore.version>
+    <commons-lang3.version>3.12.0</commons-lang3.version>
 
     <!-- Below is copied from hbase project -->
     
<hbase-surefire.jdk17.flags>-Dorg.apache.hbase.thirdparty.io.netty.tryReflectionSetAccessible=true
@@ -243,8 +257,13 @@
               <exclude>**/src/main/patches/**</exclude>
               <!--Exclude the unpacked google src-->
               <exclude>**/src/main/java/com/google/protobuf/**</exclude>
+              <exclude>**/src/main/patches/**</exclude>
               <exclude>**/src/main/resources/google/**</exclude>
               <exclude>**/src/main/java/META-INF/**</exclude>
+              <!--Exclude the unpacked libthrift src and bundled 
license/notice-->
+              
<exclude>**/hbase-shaded-thrift/src/main/java/org/apache/thrift/**</exclude>
+              
<exclude>**/hbase-shaded-thrift/src/main/resources/META-INF/LICENSE.txt</exclude>
+              
<exclude>**/hbase-shaded-thrift/src/main/resources/META-INF/NOTICE.txt</exclude>
             </excludes>
           </configuration>
         </plugin>

Reply via email to