Apache Thrift Java 库(libthrift)构建与发布全指南:源码编译、Gradle 构建、测试报告与 Maven 发布
2026/9/24 13:48:14 网站建设 项目流程
  • 后端
  • 微服务
  • API设计

【免费下载链接】thrift

Apache Thrift

项目地址:https://gitcode.com/gh_mirrors/thrift2/thrift
点击查看免费下载

Apache Thrift 的 Java 语言库(即libthrift,Maven 坐标org.apache.thrift:libthrift)是 Thrift 跨语言 RPC 框架在 JVM 生态中的核心实现。本文以仓库内 lib/java/README.md 为骨架,结合 lib/java/build.gradle、lib/java/gradle.properties、lib/java/gradle/ 下的构建脚本以及org.apache.thrift核心源码,完整讲解 libthrift 的两种构建路径(CMake 集成与纯 Gradle)、单元测试与覆盖率报告的生成、Maven Central 发布流程,以及 0.12.0 / 0.13.0 两个版本的破坏性变更。读完本文,你将能够从源码独立编译、测试、安装并发布 libthrift,同时规避升级过程中最常见的 API 兼容性问题。

一、库的定位与版本信息

Java 库在 Thrift 仓库中位于 lib/java,其 Gradle 工程名由 lib/java/settings.gradle 中的rootProject.name = 'libthrift'定义。构建所需的核心元数据集中在 lib/java/gradle.properties:

thrift.version=0.21.0 thrift.groupid=org.apache.thrift release=false # 测试执行属性 testPort=9090 # 使用 Clover 覆盖率(默认关闭) cloverEnabled=false # Maven 依赖下载地址 mvn.repo=https://repo1.maven.org/maven2 apache.repo=https://repository.apache.org/content/repositories/releases

其中thrift.version定义了产物版本号,release属性控制版本是否带有-SNAPSHOT后缀。从 lib/java/build.gradle 的实现看,版本号并非写死:

if (Boolean.parseBoolean(project.release)) { version = property('thrift.version') } else { version = property('thrift.version') + '-SNAPSHOT' }

也就是说,默认(release=false)构建出的 jar 版本形如0.21.0-SNAPSHOT,只有传入-Prelease=true时才是正式版本号0.21.0。这一点在后续"发布到 Maven Central"一节至关重要。

与大多数 Apache Thrift 语言库不同,Java 库不采用 GNU Autotools 工具链,而是使用 Java 开发者主流的Gradle构建系统。Automake(lib/java/Makefile.am)与 CMake(lib/java/CMakeLists.txt)只是外层封装,真正干活的是 Gradle 任务。

二、从源码构建与安装(CMake 集成方式)

在 Linux 上使用源码发行版的 CMake 构建时,最简单的构建与安装命令是:

make all && sudo make install/fast

这里强调必须使用install/fast选项,而不是普通的make install。原因是构建工具链在设计上会在用户主目录缓存文件,若使用带依赖自动重建的普通 install,会因为自动重建而引发问题;install/fast会在预期的本地构建树中完成编译,然后直接调用 CMake 的 install 逻辑把产物复制到目标位置,绕开这一干扰。

从 lib/java/CMakeLists.txt 可以看到这一机制的具体实现:CMake 定义一个名为ThriftJava的自定义目标,内部调用${GRADLE_EXECUTABLE} assemble生成build/libs/libthrift.jar,随后通过install(DIRECTORY ...)libthrift-${thrift_VERSION}.jar、依赖 jar 以及 javadoc 分别安装到JAVA_INSTALL_DIRJAVA_DOC_INSTALL_DIR。注释中明确写道:"This works best when 'make all && sudo make install/fast' is used"(使用make all && sudo make install/fast效果最佳),与 README 的说法相互印证。

CMake 方式还支持两种补充入口:

  • 执行make MavenPublish(CMake 生成的目标名)即可完成 Maven 发布(内部调用gradle clean uploadArchives);
  • 开启BUILD_TESTING时,会注册名为JavaTest的 CTest 测试,通过-Pthrift.compiler=${THRIFT_COMPILER}把 Thrift 编译器路径传给 Gradle 测试任务。

此外,若目标是 Android,lib/java/CMakeLists.txt 会改用android子工程构建出thrift-debug.aarthrift-release.aar

三、不使用 CMake/Autoconf 的纯 Gradle 构建

3.1 准备 Gradle 环境

当前仓库使用 Gradle 8.0 构建 Java 源码(lib/java/build.gradle 要求构建时 JDK 不低于 1.8,否则直接抛出GradleException)。常规 Gradle 项目的做法是把gradle-wrapper.jar放入工程后通过 wrapper 引导,但为了避免向源码树中提交二进制文件,本仓库有意忽略了 wrapper 文件,需要手动安装 Gradle。README 给出了与 Travis CI Docker 镜像一致的标准安装步骤:

export GRADLE_VERSION="8.4" # 安装依赖 apt-get install -y --no-install-recommends openjdk-17-jdk-headless wget unzip # 下载 Gradle 发行包 wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip # 校验二进制完整性 echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c - # 解压并安装 unzip -d /tmp /tmp/gradle-$GRADLE_VERSION-bin.zip mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle ln -s /usr/local/gradle/bin/gradle /usr/local/bin

安装完成后,gradle可执行文件位于/usr/local/bin/。如果你仍希望本地生成 wrapper(即使它被 .gitignore 忽略),可以执行:

gradle wrapper --gradle-version $GRADLE_VERSION

3.2 编译 Java 库

在 lib/java 目录下直接执行:

gradle

即可完成编译(defaultTasks 'build'已定义在 lib/java/build.gradle)。产物为libthrift-<version>.jar,位于build/libs目录。

这里的"version"受 lib/java/gradle.properties 的thrift.versionrelease共同决定,默认得到libthrift-0.21.0-SNAPSHOT.jar。构建对 JDK 版本的处理在 lib/java/gradle/sourceConfiguration.gradle 中定义:

java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.debug = true options.release = 8 // ... }

即:使用 Java 17(最新 LTS)toolchain 编译,但通过--release 8保证最终产物是 Java 8 级别的字节码,同时开启-Werror与一系列-Xlint警告检查,确保库的代码质量。这也解释了为何 CI 中还有基于 Java 11 的运行时验证。

3.3 只编译不跑测试:gradle assemble

默认的gradle(即build)会执行单元测试,而单元测试依赖系统上存在可用的 Thrift 编译器。若只想构建库而不运行测试,使用:

gradle assemble

3.4 安装到本地 Maven 仓库

如果希望其他 Maven 或 Gradle 工程能够直接引用,可执行:

gradle publishToMavenLocal

库会被安装到用户主目录下的.m2/repository中,之后即可在任意构建工具中以org.apache.thrift:libthrift:<version>坐标引用。

3.5 在应用中集成 libthrift

最简单的方式是把libthrift.jar添加到应用 classpath(或安装到默认系统 classpath)。若使用依赖管理工具,则可直接引用本地 Maven 仓库中的坐标;lib/java/gradle/publishing.gradle 中定义了完整的 Maven 坐标信息,artifactId固定为libthrift,POM 中声明了 Apache License 2.0、开发者邮箱dev@thrift.apache.org等元数据。

四、单元测试与 Thrift 编译器

4.1 测试对编译器的两种处理方式

默认构建会运行单元测试,而测试前需要用 Thrift 编译器生成测试代码,因此系统上必须存在可用的thrift可执行文件。README 给出两种选择:

  1. 从源码构建 Thrift 可执行文件,并放在源码树中的默认位置。Gradle 构建默认就会去那里寻找——lib/java/gradle/environment.gradle 中有明确逻辑:
ext.thriftRoot = rootProject.file('../..') ext.thriftCompiler = findProperty('thrift.compiler') ?: "$thriftRoot/compiler/cpp/thrift"

即默认编译器路径是仓库根目录下compiler/cpp/thrift(由 C++ 编译器工程产出)。

  1. 安装官方二进制发行版,并把路径写入~/.gradle/gradle.properties,使用属性名thrift.compiler。例如在 Windows 上若 Thrift 安装在C:\Thrift
thrift.compiler=C:/Thrift/thrift.exe

4.2 测试代码的生成与测试配置

测试用 Java 代码并非手工编写,而是由 lib/java/gradle/generateTestThrift.gradle 在构建期调用 Thrift 编译器生成到build/gen-javabuild/gen-javabeanbuild/gen-fullcamel等多个目录,默认生成器为java:jakarta_annotations,thrift 源文件取自仓库根目录 test 下的*.thrift文件。测试任务配置在 lib/java/gradle/unitTests.gradle:

  • 使用 JUnit Platform(JUnit 5),并开启测试类与方法级别的并行执行(junit.jupiter.execution.parallel.enabled=true);
  • 堆上限maxHeapSize = '512m'
  • 默认测试端口来自gradle.propertiestestPort=9090
  • 注入javax.net.ssl.trustStore/keyStore等 SSL 系统属性(指向src/crossTest/resources下的.truststore/.keystore),供 TLS 相关测试使用。

4.3 HTML 单元测试报告

构建会自动生成 HTML 格式的单元测试报告,位置在:

build/reports/tests/test/index.html

可直接用浏览器打开查看。

五、Clover 代码覆盖率报告

构建支持可选的 Clover 覆盖率统计,通过 Gradle 属性cloverEnabled=true开启,可在~/.gradle/gradle.properties中设置,或通过命令行-PcloverEnabled=true传入。生成报告的位置:

  • HTML 报告:build/reports/clover/html/index.html
  • PDF 报告:build/reports/clover/clover.pdf

一条命令完成"构建 + 单元测试 + Clover 报告":

gradle -PcloverEnabled=true

从 lib/java/gradle/cloverCoverage.gradle 的实现看,该特性默认关闭(cloverEnabled=false定义于 lib/java/gradle.properties),仅在属性为 true 时才应用com.bmuschko.clover插件,并设置testIncludes = ['**/Test*.java']、排除自动生成的thrift/test/Test*.java,报告同时输出 HTML 与 PDF,且build任务依赖cloverGenerateReport

六、代理环境下的构建

在企业内网或需要代理访问外网依赖时,可通过 JVM 系统属性指定 HTTP 代理:

gradle -Dhttp.proxyHost=myproxyhost -Dhttp.proxyPort=8080 -Dhttp.proxyUser=thriftuser -Dhttp.proxyPassword=topsecret

若使用 Autotools/CMake 方式构建(即外层调用 configure 生成 Makefile),可通过环境变量透传同样的参数:

./configure --with-java GRADLE_OPTS='-Dhttp.proxyHost=myproxyhost -Dhttp.proxyPort=8080 -Dhttp.proxyUser=thriftuser -Dhttp.proxyPassword=topsecret'

七、发布 Maven 制品到 Maven Central

7.1 通过 Automake / CMake 触发发布

Automake 构建生成的 Makefile 会在运行构建时提供正确参数(前提是 configure.ac 已设置正确版本号);CMake 构建同理,会读取configure.ac中的版本值。执行以下命令之一即可:

make maven-publish # Automake Linux 构建 make MavenPublish # CMake 生成的构建

从 lib/java/Makefile.am 可见,maven-publish实际执行的是gradle publish -Prelease=true -Pthrift.version=$(PACKAGE_VERSION);lib/java/CMakeLists.txt 中的MavenPublish目标则执行gradle clean uploadArchives。二者都以-Prelease=true强制使用正式版本号。

7.2 配置签名与认证信息

Gradle 的publish任务已预配置了向 Apache Maven staging 仓库签名并发布制品所需的全部细节,但需要外部提供以下属性用于仓库认证与制品 PGP 签名。推荐在~/.gradle/gradle.properties中创建/编辑:

# 制品 PGP 签名的密钥信息(示例值) signing.keyId=24875D73 signing.password=secret signing.secretKeyRingFile=/Users/me/.gnupg/secring.gpg # Apache Maven staging 仓库的用户凭据 mavenUser=meMyselfAndI mavenPassword=MySuperAwesomeSecretPassword

如果没有secring.gpg文件,可参考 Gradle 官方 signing 插件文档生成(注意:新版 GnuPG 生成的通常是*.gpg私钥文件而非secring.gpg,可根据实际情况调整signing.secretKeyRingFile指向)。

从 lib/java/gradle/publishing.gradle 的实现看,签名逻辑为:

signing { required { !version.endsWith("SNAPSHOT") && gradle.taskGraph.hasTask("publish") } sign publishing.publications.mavenJava }

即只有发布非 SNAPSHOT版本且确实执行publish任务时才会要求签名;仓库凭据则仅在同时提供mavenUsermavenPassword两个属性时注入。

7.3 使用 Gradle 手动发布

凭据与密钥就绪后,执行:

gradle -Prelease=true publish

该命令会按需生成构建产物并完成发布。注意这里同样要加-Prelease=true,否则产物版本带-SNAPSHOT后缀,签名与仓库路径行为都会不同。

7.4 覆盖目标仓库地址

通过 Gradle 属性maven-repository-url可以覆盖默认的发布目标仓库(默认值定义在 lib/java/gradle.properties:maven-repository-url=https://repository.apache.org/service/local/staging/deploy/maven2)。例如把签名后的 jar 发布到公司内部 Nexus 服务器:

maven-repository-url=https://my.company.com/service/local/staging/deploy/maven2

或在命令行一次性指定(以下示例同时覆盖了仓库地址、强制 release 版本并显式指定版本号):

gradle -Pmaven-repository-url=https://my.company.com/service/local/staging/deploy/maven2 -Prelease=true -Pthrift.version=0.11.0 publish

八、依赖说明

libthrift 的编译期依赖与测试依赖全部声明在 lib/java/gradle/environment.gradle,版本号统一托管在 lib/java/gradle.properties:

依赖用途
org.slf4j:slf4j-api日志门面
org.apache.httpcomponents.client5:httpclient5/httpcore5HTTP 传输层(THttpClient)
jakarta.servlet:jakarta.servlet-api嵌入式 Servlet 服务器支持
jakarta.annotation:jakarta.annotation-apiJakarta 注解
org.apache.commons:commons-lang3通用工具
org.junit.jupiter:junit-jupiterorg.mockito:mockito-core单元测试框架(仅测试期)

依赖仓库默认指向 Maven Central(mvn.repo)与 Apache 发行仓库(apache.repo)。构建时还会把仓库根目录的 LICENSE 与 NOTICE 文件以META-INF/*.txt形式打入 jar(见 lib/java/gradle/sourceConfiguration.gradle 的processResources配置)。

九、破坏性变更与升级注意事项

README 末尾专门记录了升级时需要关注的破坏性变更,这些都可以在当前仓库源码中得到印证。

9.1 0.13.0:TAsyncProcessor / TProcessor 的 process 方法签名变更

TAsyncProcessorTProcessorprocess方法的签名发生了变化:移除了 boolean 返回值,改为依赖异常表达处理结果

对照当前源码 lib/java/src/main/java/org/apache/thrift/TProcessor.java:

public interface TProcessor { void process(TProtocol in, TProtocol out) throws TException; }

以及 lib/java/src/main/java/org/apache/thrift/TAsyncProcessor.java:

public interface TAsyncProcessor { void process(final AsyncFrameBuffer fb) throws TException; }

两个接口的process现在都是void返回、通过抛出TException表达失败。升级到 0.13.0 及以后版本时,所有自定义的 TProcessor / TAsyncProcessor 实现都必须相应调整方法签名。

9.2 0.13.0:TSaslTransportException 移除(THRIFT-4805)

TSaslTransportException已被移除(对应 JIRA 单 THRIFT-4805),原来由该异常表达的"对端提前关闭/文件结束"场景,现在统一由TTransportException覆盖,判定条件为:

TTransportException.getType() == END_OF_FILE

END_OF_FILE常量定义在 lib/java/src/main/java/org/apache/thrift/transport/TTransportException.java:

public static final int UNKNOWN = 0; public static final int NOT_OPEN = 1; public static final int ALREADY_OPEN = 2; public static final int TIMED_OUT = 3; public static final int END_OF_FILE = 4; public static final int CORRUPTED_DATA = 5;

9.3 0.12.0:AutoExpandingBuffer 与 ShortStack 可见性收窄

0.12.0 将AutoExpandingBufferShortStack两个内部优化类的访问修饰符从public改为默认(包内)级别,第三方库不再能直接访问。

对照当前源码:ShortStack在 lib/java/src/main/java/org/apache/thrift/protocol/ShortStack.java 中确实以包私有形式存在(class ShortStack),其 Javadoc 说明它是为TCompactProtocol的 field id 栈量身定制的short专用栈实现,性能约为java.util.Stack的 10 倍以上。而AutoExpandingBuffer(lib/java/src/main/java/org/apache/thrift/transport/AutoExpandingBuffer.java)在当前 0.21.0 源码中显示为public class——README 记载的是 0.12.0 当时的变化,若你的第三方代码在 0.12.0 之后仍能引用到该类,说明其可见性在后续版本中又得到了恢复。升级建议:无论当前可见性如何,这类内部优化类都未被承诺为公共 API,第三方代码不应依赖它们。

十、小结

围绕 lib/java/README.md,本文完整还原了 Apache Thrift Java 库的工程化全景:

  • 两条构建路径:CMake 集成(make all && sudo make install/fast)与纯 Gradle(gradle/gradle assemble/gradle publishToMavenLocal),产物统一为build/libs/libthrift-<version>.jar
  • 测试与质量门禁:单元测试依赖 Thrift 编译器(默认compiler/cpp/thrift,可用thrift.compiler属性覆盖),HTML 报告位于build/reports/tests/test/index.html,可选 Clover 覆盖率(-PcloverEnabled=true);
  • 发布链路:通过make maven-publish/make MavenPublishgradle -Prelease=true publish配合签名与认证属性发布到 Maven Central,maven-repository-url可覆盖目标仓库;
  • 升级红线:0.13.0 的process方法签名变化与TSaslTransportException移除、0.12.0 的AutoExpandingBuffer/ShortStack可见性收窄,均可在 lib/java/src/main/java/org/apache/thrift 源码中找到对应实现。

无论你是想为定制化需求编译本地 libthrift,还是计划向 Maven 仓库发布内部版本,亦或是正在评估从旧版本升级的兼容性成本,上述命令、属性与源码依据都可以直接作为实操参考。若需进一步了解库的编码规范,可阅读 lib/java/coding_standards.md;各 Gradle 构建脚本(environment.gradle、unitTests.gradle、publishing.gradle 等)也是理解构建细节的第一手资料。

  • 后端
  • 微服务
  • API设计

【免费下载链接】thrift

Apache Thrift

项目地址:https://gitcode.com/gh_mirrors/thrift2/thrift
点击查看免费下载

相关推荐

上一篇:Scrutor装饰器链式调用:构建复杂业务逻辑的完整解决方案
下一篇:OpenVAS Scanner:开源漏洞扫描器的终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询