编译kafka 0.8.2.2,解决bug kafka.common.InvalidTopicException: topic name kafka:h5_send_msg is illegal, contains a character other than ASCII alphanumerics, '.', '_' and '-'
一: 背景说明
异常信息:
[2017-10-23 10:41:32,793] ERROR [KafkaApi-2] error when handling request Name: TopicMetadataRequest; Version: 0; CorrelationId: 1167300213; ClientId: producer-1; Topics: h5_page_action_new,game_brain_gc_community_data,basic_log,friend_pay_new,r_talk_new,active_log_new,pay_log_new,one_key_login_device_new,player_location_new,report_module_log,download_game_log,sdk_function_log_new,mchannel_player_behavior_new,php_api_log_new,wap_h5_pay_new,kafka:h5_send_msg,game_action_interface_log_new,game_log-mm_lrs_xdksgq (kafka.server.KafkaApis)
kafka.common.InvalidTopicException: topic name kafka:h5_send_msg is illegal, contains a character other than ASCII alphanumerics, '.', '_' and '-'
at kafka.common.Topic$.validate(Topic.scala:42)
at kafka.admin.AdminUtils$.createOrUpdateTopicPartitionAssignmentPathInZK(AdminUtils.scala:181)
at kafka.admin.AdminUtils$.createTopic(AdminUtils.scala:172)
at kafka.server.KafkaApis$$anonfun$19.apply(KafkaApis.scala:520)
at kafka.server.KafkaApis$$anonfun$19.apply(KafkaApis.scala:503)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.immutable.HashSet$HashSet1.foreach(HashSet.scala:322)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
at scala.collection.AbstractSet.scala$collection$SetLike$$super$map(Set.scala:47)
at scala.collection.SetLike$class.map(SetLike.scala:92)
at scala.collection.AbstractSet.map(Set.scala:47)
at kafka.server.KafkaApis.getTopicMetadata(KafkaApis.scala:503)
at kafka.server.KafkaApis.handleTopicMetadataRequest(KafkaApis.scala:542)
at kafka.server.KafkaApis.handle(KafkaApis.scala:62)
at kafka.server.KafkaRequestHandler.run(KafkaRequestHandler.scala:59)
at java.lang.Thread.run(Thread.java:724)
apache官方bug说明:
https://issues.apache.org/jira/browse/KAFKA-1884
github源码:
https://github.com/apache/kafka/tree/0.8.2.2/clients/src/main/java/org/apache/kafka/clients
https://github.com/apache/kafka/blob/0.8.2.2/clients/src/main/java/org/apache/kafka/clients/NetworkClient.java
patch:
https://issues.apache.org/jira/secure/attachment/12701885/KAFKA-1884.patch
二:
Gradle
安装配置
Kafka代码自0.8.x之后就使用Gradle来进行编译和构建了,因此首先需要安装Gradle。Gradle集成并吸收了Maven主要优点的同时还克服了Maven自身的一些局限性——你可以访问https://www.gradle.org/downloads/ 下载最新的Gradle版本。下载解压到一个目录,然后创建一个环境变量GRADLE_HOME指向解压的目录,再将%GRADLE_HOME%\bin加到PATH环境变量中,Gradle就安装配置好了。打开一个cmd输入gradle -v 验证一下:
三:
Kafka源代码下载
安装好Gradle之后我们开始下载Kafka的源代码,当前最新的稳定版本是0.10.0.1,目前我们使用的是0.9.0.1版本,你可以从http://kafka.apache.org/downloads.html 或者 github 处下载源代码包。下载之后解压缩到一个目录,目录结构如下图所示:
重要目录的作用如下:
bin目录: Windows和Unix平台下的执行脚本,比如kafka-server-start,console-producer,console-consumer等
clients目录: Kafka客户端代码
config目录: Kafka配置文件,其中比较重要的是server.properties,启动Kafkabroker需要直接加载这个文件
contrib目录: Kafka与hadoop集成的代码,包括hadoop-consumer和hadoop-producer
core目录: Kafka的核心代码,也是作者后面重点要学习的部分
examples目录: Kafka样例代码,例如如何使用Java编写简单的producer和consumer
system_test: 系统测试脚本,主要用python编写
其他的目录和配置文件大多和gradle配置有关,就不赘述了。
四:生成IDEA工程文件并导入到IDEA中
上述准备工作一切就绪后,我们现在可以生成IDEA工程文件。具体做法为打开一个cmd窗口,切换到kafka源代码根路径下,运行gradle idea,如果是第一次运行,可能会花费一些时间去下载必要的jar包,在等待了一段时间之后,终于看到了BUILDSUCCESSFUL的字样表示项目工程文件生成成功:
问题:
执行gradle idea时,报错
gradle idea
Starting a Gradle Daemon (subsequent builds will be faster)
Building project 'core' with Scala version 2.10.6
FAILURE: Build failed with an exception.
* Where:
Build file '/opt/bigdata/kafka/kafka-0.10.0.0-src/build.gradle' line: 230
* What went wrong:
A problem occurred evaluating root project 'kafka-0.10.0.0-src'.
> Failed to apply plugin [class 'org.gradle.api.plugins.scala.ScalaBasePlugin']
> No such property: useAnt for class: org.gradle.api.tasks.scala.ScalaCompileOptions
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
解决方法:vim kafka-0.10.0.0-src/build.gradle文件
添加如下行
- ScalaCompileOptions.metaClass.daemonServer = true
- ScalaCompileOptions.metaClass.fork = true
- ScalaCompileOptions.metaClass.useAnt = false
- ScalaCompileOptions.metaClass.useCompileDaemon = false
如图:
项目导入到IDEA工程中
File-->Open
源码目录:
五:执行编译
进入kafka目录:
cd /Users/rolin/IdeaProjects/kafka-0.8.2.2
执行编译命令:
gradle build -x test
其中的-x test表示跳过unit test
结果成功:
六:替换对应jar包目录
编译完成对应的jar包:
替换原来的kafka-client-0.8.2.2.jar即可