我遇到了Kafka 0.9无法通过Java客户端创建主题的奇怪问题。
给出以下代码 -
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import kafka.admin.AdminUtils;
import kafka.utils.ZKStringSerializer$;
import kafka.utils.ZkUtils;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkConnection;
import scala.collection.JavaConversions;
/**
* This class contains static methods to operate on queues, allowing queue
* creation and deletion, checking whether queues exist on the broker, and
* listing all queues on the broker.
*
* A topic represents a queue.
*/
public class Topic
{
private static final int DEFAULT_SESSION_TIMEOUT = 10 * 1000;
private static final int DEFAULT_CONNECTION_TIMEOUT = 8 * 1000;
private static final String ZOOKEEPER_CONNECT = "localhost:2181";
/**
* Opens a new ZooKeeper client to access the Kafka broker.
*/
private static ZkClient connectToZookeeper ()
{
return new ZkClient(ZOOKEEPER_CONNECT,
DEFAULT_SESSION_TIMEOUT,
DEFAULT_CONNECTION_TIMEOUT,
ZKStringSerializer$.MODULE$);
}
/**
* Given a ZooKeeper client instance, accesses the broker and returns
* information about Kafka's contents.
*
* @param zookeeperClient A ZooKeeper client to access broker information
* through.
*/
private static ZkUtils zookeeperUtility (ZkClient zookeeperClient)
{
boolean isSecureCluster = false;
return new ZkUtils(zookeeperClient,
new ZkConnection(ZOOKEEPER_CONNECT),
isSecureCluster);
}
/**
* Given its name, checks if a topic exists on the Kafka broker.
*
* @param name The name of the topic.
*
* @return <code>true</code> if the topic exists on the broker,
* <code>false</code> if it doesn't.
*/
public static boolean existsTopic (String name)
{
ZkClient zkClient = connectToZookeeper();
ZkUtils zkUtils = zookeeperUtility(zkClient);
boolean topicExists = AdminUtils.topicExists(zkUtils, name);
zkClient.close();
return topicExists;
}
/**
* Creates new topics, which remain persistent on the Kafka broker.
*
* @param names The names of the topic.
* @param partitions The number of partitions in the topic.
* @param replication The number of brokers to host the topic.
*/
public static void createTopics (ArrayList<String> names, int partitions, int replication)
{
ZkClient zkClient = connectToZookeeper();
ZkUtils zkUtils = zookeeperUtility(zkClient);
for (String name: names)
{
if (existsTopic(name))
continue;
AdminUtils.createTopic(zkUtils, name, partitions, replication, new Properties());
}
zkClient.close();
}
/**
* Given its name, deletes a topic on the Kafka broker.
*
* @param names The name of the topic.
*/
public static void deleteTopics (ArrayList<String> names)
{
ZkClient zkClient = connectToZookeeper();
ZkUtils zkUtils = zookeeperUtility(zkClient);
for (String name: names)
{
if (!existsTopic(name))
return;
AdminUtils.deleteTopic(zkUtils, name);
}
zkClient.close();
}
/**
* Lists all topics on the Kafka broker.
*/
public static void listTopics ()
{
ZkClient zkClient = connectToZookeeper();
ZkUtils zkUtils = zookeeperUtility(zkClient);
List<String> brokerTopics = JavaConversions.seqAsJavaList(zkUtils.getAllTopics());
for (String topic: brokerTopics)
System.out.println(topic);
zkClient.close();
}
}
deleteTopics()
和existsTopic()
工作正常,暗示一切都是最新的,我正确访问AdminUtils方法。但是,createTopics()
在运行时崩溃,但出现以下异常 - java.lang.NoClassDefFoundError: scala/Product$class
可能会发生什么?
答案 0 :(得分:0)
有two Kafka compiles需要不同的Scala库,Scala 2.10或Scala 2.11。如果您使用下载站点中的两个tgz之一,则会获得正确的scala库作为其中一部分。如果你使用maven,你可能需要单独添加依赖项(我只使用过tgz,所以我不知道maven的依赖。)