解决 IDEA 阅读 Hadoop 源码报错问题

最近阅读 Hadoop 源码,使用 IDEA 打开 Hadoop,正常导入 maven 依赖后,发现某些类里面总是会报各种类不存在的错误,如下图:

2020-12-28-5YtjEW

一开始以为是因为我配置了国内 maven 镜像仓库,然后国内镜像仓库里面某些 jar 包没有及时同步,导致的缺失。但是我看了看 maven 中的导入记录,发现并没有报 jar 包找不到的错误。

看了看缺失的类,它们的包名基本都含有 proto 关键字,结合 Hadoop 是使用 protobuf 作为序列化框架,经过我的一番推理,我认为这些缺失的类是需要通过 protobuf 的命令行工具 protoc 产生的,源码里面默认是不带的。

找到了问题,就开始解决,这里我把我的解决思路贴出来,也许不是最好的方法,但是也是目前我能想到最合适的。

我这里不会写明细节上面的操作。

我的 Hadoop 源码为 3.3.0,JDK 版本为 1.8,protobuf 按照源码的要求,安装的是 3.7.1 版本。

方法一, protoc 直接编译,失败

我打算直接使用 protobuf 工具对 .proto 后缀文件进行编译,然而奇怪的事情发生了。这里我以 hadoop-3.3.0-src/hadoop-common-project/hadoop-common/src/main/proto 为例,我使用 protoc --java_out=../ *.proto 命令编译该目录下的所有 .proto 文件。但是报了如下错误:

ProtobufRpcEngine2.proto:46:19: "hadoop.common.RequestHeaderProto.methodName" is already defined in file "ProtobufRpcEngine.proto".
ProtobufRpcEngine2.proto:63:19: "hadoop.common.RequestHeaderProto.declaringClassProtocolName" is already defined in file "ProtobufRpcEngine.proto".
ProtobufRpcEngine2.proto:66:19: "hadoop.common.RequestHeaderProto.clientProtocolVersion" is already defined in file "ProtobufRpcEngine.proto".
ProtobufRpcEngine2.proto:44:9: "hadoop.common.RequestHeaderProto" is already defined in file "ProtobufRpcEngine.proto".

大概就是 message 重复了,因为有些 message 同时出现在了不同的 .proto 文件中。那我就单独每个文件执行一次 protoc 命令,这样确实可行,就是累死了,整个 Hadoop 有很多 .proto 文件 ,一个一个编译肯定不行。

此外你看看上面的错误,相同的 message 同时出现在 ProtobufRpcEngine2.protoProtobufRpcEngine.proto 文件中,那我怎么知道应该使用哪一个 .proto 呢。

方法二,直接 Maven 编译,失败

既然 protoc 命令不行,那我直接按照官方的 BUILDING 文档,直接吧 Hadoop 源码编译一轮,那不就会生成 proto 文件了。我使用的系统是 Mac OS Big Sur,然后我按照 BUILDING 中 Mac 的方法进行编译,然后 mvn 编译的时候老是在 cmake 那里报错,说找不到 zlib,但是我 zlib 明明是有的。而且看到 BUILDING 后面还写着:

Note that building Hadoop 3.1.1/3.1.2/3.2.0 native code from source is broken on macOS. For 3.1.1/3.1.2, you need to manually backport YARN-8622. For 3.2.0, you need to backport both YARN-8622 and YARN-9487 in order to build native code.

瞬间我就放弃了,感觉就算我解决了这个问题,可能后面还有更多的坑。

方法三,远程开发,失败

既然 Mac 不行,然我用 Linux 系统如 Centos 进行编译,然后 IDEA 远程开发不就行了。但是整个 Hadoop 项目过于庞大,每一次 IDEA 同步都要浪费好久的时间,这样肯定也是不行的。因为 IDEA 的 remote development 要求本地和远程都有一份代码。那有没有什么办法能直接编辑远程的代码而不需要本地有吗?

当然有,用 VS Code 的远程开发,然而 VS Code 并没有比 IDEA 好用在哪里。Maven jar 包的识别配置麻烦,而且代码自动推理不如 IDEA 好用。

曲线救国,成功

最后,找了一个方法曲线救国,这里简单说明下:

  1. 使用自己的一台服务器 or 虚拟机 or Docker 均可,进行编译 Hadoop 源码。
  2. 我个人是使用了腾讯云的轻量服务器。Docker 的话直接运行源码里面的 start-build-env.sh 脚本就行了,然后编译。
  3. 注意,生成的类是不会直接出现在源码里面,因为是通过 Maven 编译,编译的 Java 文件在 xxx/target/generated-sources/java 中。像我用的是腾讯云,可以通过 IDEA 中的 Remote Host 打开远程目录,将那些生成的类直接拖到源码里面即可。
2020-12-28-ULvv7e

原创文章,作者:Smith,如若转载,请注明出处:https://www.inlighting.org/archives/solve-idea-hadoop-errors

打赏 微信扫一扫 微信扫一扫
SmithSmith
上一篇 2019年10月6日
下一篇 2021年1月21日

相关推荐

  • Apache ORC 加密解析

    Apache ORC 支持对列进行加密,且会对该列的统计信息一起加密。同时加密后的文件,即使 reader 没有正确的 master key 也能够正常的查看,只不过看到的都是错误…

    2024年7月7日
    1690
  • 浅谈 Apache ORC 之 Decimal 存储

    Decimal 在 Apache ORC 存储主要是依赖 zigzag 编码,zigzag 编码能有效的压缩绝对值小的数字。

    2024年5月5日
    2481
  • ORC vs Parquet,孰强孰弱?

    本文深入探讨了 ORC 和 Parquet 这两种主流数据湖文件格式的异同。从文件结构、类型系统、NULL处理到复杂类型存储,文章全面比较了两种格式的设计理念和实现细节。特别关注了统计信息的存储、随机 IO 性能、Footer 大小以及 Schema Evolution 支持等关键方面。虽然Parquet 在当前市场占据优势,但文章指出两种格式各有千秋,选择应基于具体使用场景。通过这篇深度分析,读者可以更好地理解这两种格式的优缺点,为数据湖存储方案的选择提供有价值的参考。

    2024年8月10日
    4242

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

评论列表(1条)

  • dirtysalt
    dirtysalt 2023年9月1日 下午2:03

    Remote Host是专业版本的功能吗?