开篇絮叨
背景
垂青于阿里吹捧的流批一体,迫不及待下载了flink1.12.1,按照flink的官方教程,下载了依赖包,
放进了lib文件夹,一个命令跑起来,结果就报了“NoSuchMethodError: com.google.common.base.Preconditions.checkArgument”
这个让我废寝忘食了一个星期的错,期间的痛苦折磨,抓心挠肺,必须记载下,忘后面遇到的人都能跳过去,
不用重蹈覆辙,我会尽量详细记录,主要是flink的源码编译过程。
问题定位
根据百度,这个错误主要是guava库冲突导致,flink1.12.1的guava库是29.0-jre,
我使用的是HDP的hive3.1.0,使用的guava版本是28.0-jre,我们放在flink的lib文件下的
flink-sql-connector-hive-3.1.2_2.12-1.12.1.jar包里的guava的版本是19.0。
所以吧,重新编译flink源码,解决版本冲突即可。理想很丰满,我是太乐观了!
源码编译
准备
maven的安装,这里不介绍了。
下载
wget https://archive.apache.org/dist/flink/flink-1.12.1/flink-1.12.1-src.tgz
配置
maven源配置
我使用的是HDP的环境,需要添加cloudera和hdp的源,这个很重要,相信国内还是很多人使用CDH或者HDP部署集群的。
// An highlighted block
<repositories>
<!-- Cloudera -->
<repository>
<id>cloudera-releases</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!-- Hortonworks -->
<repository>
<id>HDPReleases</id>
<name>HDP Releases</name>
<url>https://repo.hortonworks.com/content/repositories/releases/</url>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
</repository>
<repository>
<id>HortonworksJettyHadoop</id>
<name>HDP Jetty</name>
<url>https://repo.hortonworks.com/content/repositories/jetty-hadoop</url>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
</repository>
<!-- MapR -->
<repository>
<id>mapr-releases</id>
<url>https://repository.mapr.com/maven/</url>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
</repository>
</repositories>
版本配置
在项目的根目录的pom.xml中根据自己环境配置,主要修改的是hadoop.version和hive.version,
可以在自己集群去查看。
// An highlighted block
hadoop version
hive --version
编译
// An highlighted block
mvn clean install -Dfast -Dhadoop.version=3.1.1.3.1.4.0-315 -Dscala-2.12 -DskipTests -Dfast -T 4 -Dmaven.compile.fork=true -Dmaven.javadoc.skip=true -Dcheckstyle.skip=true
注意修改成你自己的hadoop版本
问题
flink源码的管理是真的有些问题,编译不过,下面是我发现的一些问题。
缺少依赖
编译过程中发现好几个报找不到符号的错,集中在hadoop文件的几个jar包,发现pom.xml中未加依赖,加上即可。
解决方案:
在 flink-filesystems/flink-hadoop-fs/pom.xml的dependencies添加:
// An highlighted block
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs-client</artifactId>
<version>${hadoop.version}</version><!--$NO-MVN-MAN-VER$-->
</dependency>
HIVE版本
最核心的这个问题,在flink-connectors/flink-sql-connector-hive-3.1.2/pom.xml中:
// An highlighted block
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.2</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
这里hive版本写死了3.1.2,但是我们适配的是HDP的3.1.2,所以hive版本要写你根目录里pom.xml的那个版本,这样才不会有guava适配的问题。改成${hive.version}。
骂个街
百度是真不好用,查了一圈,不知所云。下了个谷歌助手,用谷歌搜了下,也没发现有价值的东西。
直到自己用mvn dependency:tree | less逐个查依赖,看看到底谁用了guava19.0,
才发现是hive-exec这个jar包,进而发现这里hive版本写死了,不是HDP适配的hive版本。
修改完,重新编译,再查看guava版本,已经是guava28.0-jre了,用新的版本再跑flink,就完全没问题了。