単純なKafka Producer&Consumerを作成しています。kafka_2.11-0.9.0.0を使用しています。これが私のプロデューサーコードです。
public class KafkaProducerTest {
public static String topicName = "test-topic-2";
public static void main(String[] args) {
// TODO Auto-generated method stub
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer",
StringSerializer.class.getName());
props.put("value.serializer",
StringSerializer.class.getName());
Producer<String, String> producer = new KafkaProducer(props);
for (int i = 0; i < 100; i++) {
ProducerRecord<String, String> producerRecord = new ProducerRecord<String, String>(
topicName, Integer.toString(i), Integer.toString(i));
System.out.println(producerRecord);
producer.send(producerRecord);
}
producer.close();
}
}
バンドルを開始している間、私は以下のエラーに直面しています:
2016-05-20 09:44:57,792 | ERROR | nsole user karaf | ShellUtil | 44 - org.Apache.karaf.Shell.core - 4.0.3 | Exception caught while executing command
org.Apache.karaf.Shell.support.MultiException: Error executing command on bundles:
Error starting bundle162: Activator start error in bundle NewKafkaArtifact [162].
at org.Apache.karaf.Shell.support.MultiException.throwIf(MultiException.Java:61)
at org.Apache.karaf.bundle.command.BundlesCommand.doExecute(BundlesCommand.Java:69)[24:org.Apache.karaf.bundle.core:4.0.3]
at org.Apache.karaf.bundle.command.BundlesCommand.execute(BundlesCommand.Java:54)[24:org.Apache.karaf.bundle.core:4.0.3]
at org.Apache.karaf.Shell.impl.action.command.ActionCommand.execute(ActionCommand.Java:83)[44:org.Apache.karaf.Shell.core:4.0.3]
at org.Apache.karaf.Shell.impl.console.osgi.secured.SecuredCommand.execute(SecuredCommand.Java:67)[44:org.Apache.karaf.Shell.core:4.0.3]
at org.Apache.karaf.Shell.impl.console.osgi.secured.SecuredCommand.execute(SecuredCommand.Java:87)[44:org.Apache.karaf.Shell.core:4.0.3]
at org.Apache.felix.gogo.runtime.Closure.executeCmd(Closure.Java:480)[44:org.Apache.karaf.Shell.core:4.0.3]
at org.Apache.felix.gogo.runtime.Closure.executeStatement(Closure.Java:406)[44:org.Apache.karaf.Shell.core:4.0.3]
at org.Apache.felix.gogo.runtime.Pipe.run(Pipe.Java:108)[44:org.Apache.karaf.Shell.core:4.0.3]
at org.Apache.felix.gogo.runtime.Closure.execute(Closure.Java:182)[44:org.Apache.karaf.Shell.core:4.0.3]
at org.Apache.felix.gogo.runtime.Closure.execute(Closure.Java:119)[44:org.Apache.karaf.Shell.core:4.0.3]
at org.Apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.Java:94)[44:org.Apache.karaf.Shell.core:4.0.3]
at org.Apache.karaf.Shell.impl.console.ConsoleSessionImpl.run(ConsoleSessionImpl.Java:270)[44:org.Apache.karaf.Shell.core:4.0.3]
at Java.lang.Thread.run(Thread.Java:745)[:1.8.0_66]
Caused by: Java.lang.Exception: Error starting bundle162: Activator start error in bundle NewKafkaArtifact [162].
at org.Apache.karaf.bundle.command.BundlesCommand.doExecute(BundlesCommand.Java:66)[24:org.Apache.karaf.bundle.core:4.0.3]
... 12 more
Caused by: org.osgi.framework.BundleException: Activator start error in bundle NewKafkaArtifact [162].
at org.Apache.felix.framework.Felix.activateBundle(Felix.Java:2276)[org.Apache.felix.framework-5.4.0.jar:]
at org.Apache.felix.framework.Felix.startBundle(Felix.Java:2144)[org.Apache.felix.framework-5.4.0.jar:]
at org.Apache.felix.framework.BundleImpl.start(BundleImpl.Java:998)[org.Apache.felix.framework-5.4.0.jar:]
at org.Apache.karaf.bundle.command.Start.executeOnBundle(Start.Java:38)[24:org.Apache.karaf.bundle.core:4.0.3]
at org.Apache.karaf.bundle.command.BundlesCommand.doExecute(BundlesCommand.Java:64)[24:org.Apache.karaf.bundle.core:4.0.3]
... 12 more
Caused by: org.Apache.kafka.common.config.ConfigException: Invalid value org.Apache.kafka.common.serialization.StringSerializer for configuration key.serializer: Class org.Apache.kafka.common.serialization.StringSerializer could not be found.
at org.Apache.kafka.common.config.ConfigDef.parseType(ConfigDef.Java:255)[141:kafka-examples:1.0.0.SNAPSHOT-jar-with-dependencies]
at org.Apache.kafka.common.config.ConfigDef.parse(ConfigDef.Java:145)[141:kafka-examples:1.0.0.SNAPSHOT-jar-with-dependencies]
at org.Apache.kafka.common.config.AbstractConfig.<init>(AbstractConfig.Java:49)[141:kafka-examples:1.0.0.SNAPSHOT-jar-with-dependencies]
at org.Apache.kafka.common.config.AbstractConfig.<init>(AbstractConfig.Java:56)[141:kafka-examples:1.0.0.SNAPSHOT-jar-with-dependencies]
at org.Apache.kafka.clients.producer.ProducerConfig.<init>(ProducerConfig.Java:317)[141:kafka-examples:1.0.0.SNAPSHOT-jar-with-dependencies]
at org.Apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.Java:181)[141:kafka-examples:1.0.0.SNAPSHOT-jar-with-dependencies]
at com.NewKafka.NewKafkaArtifact.KafkaProducerTest.main(KafkaProducerTest.Java:25)[162:NewKafkaArtifact:0.0.1.SNAPSHOT]
at com.NewKafka.NewKafkaArtifact.StartKafka.start(StartKafka.Java:11)[162:NewKafkaArtifact:0.0.1.SNAPSHOT]
at org.Apache.felix.framework.util.SecureAction.startActivator(SecureAction.Java:697)[org.Apache.felix.framework-5.4.0.jar:]
at org.Apache.felix.framework.Felix.activateBundle(Felix.Java:2226)[org.Apache.felix.framework-5.4.0.jar:]
... 16 more
key.serializer
とvalue.serializer
を次のように設定してみました。
props.put("key.serializer",StringSerializer.class.getName());
props.put("value.serializer",StringSerializer.class.getName());
同様に、しかしそれでも同じエラーが発生します。私はここで何が間違っているのですか。
props.put("key.serializer", "org.Apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.Apache.kafka.common.serialization.StringSerializer");
使用しているバージョンでの問題。バージョン0.8.2.2_1にも提案されました。使用しているkafkaのバージョンを調整して、試してみることをお勧めします。コードに関しては、kafka開発リストにある多くのコードサンプルをクロスチェックしました。あなたは正しい方法で書いています。
つまり、Thread.currentThread().setContextClassLoader(null);
kafkaクライアントのソースコードを読んで理由を見つけます。
kafkaクライアントはClass.forName(trimmed, true, Utils.getContextOrKafkaClassLoader())
を使用してClassオブジェクトを取得し、インスタンスを作成します。重要なポイントは、最後のパラメーターで指定されたclassLoaderであり、メソッドUtils.getContextOrKafkaClassLoader()
の実装は次のとおりです。
public static ClassLoader getContextOrKafkaClassLoader() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null)
return getKafkaClassLoader();
else
return cl;
}
したがって、デフォルトでは、org.Apache.kafka.common.serialization.StringSerializer
のClassオブジェクトはapplicationClassLoaderによってロードされます。ターゲットクラスがapplicationClassLoaderによってロードされない場合、この問題が発生します。
この問題を解決するには、次のような新しいKafkaProducerインスタンスの前に、現在のスレッドのContextClassLoaderをnullに設定するだけです。
Thread.currentThread().setContextClassLoader(null);
Producer<String, String> producer = new KafkaProducer(props);
私の答えがあなたに何が起こったのかを知らせることができることを願っています。
@Ram Ghadiyaramが彼の回答で示したように、問題はクラスローダーにあるようです。これをkafka-clients2.xで機能させるには、次のことを行う必要がありました。
public Producer<String, String> createProducer() {
ClassLoader original = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(null);
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,
BOOTSTRAP_SERVERS);
... etc ...
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
Thread.currentThread().setContextClassLoader(original);
return producer;
}
これにより、システムは元のクラスローダーで追加のクラスをロードし続けることができます。これはWildfly/JBossで必要でした(私が使用している特定のアプリはKeycloakです)。
最近私は解決策を見つけました。 Thead Contextローダーをnullに設定すると、問題が解決しました。ありがとう。
Thread.currentThread().setContextClassLoader(null);
Producer<String, String> producer = new KafkaProducer(props);
あなたの小道具の代わりにこれらの小道具を使ってみてください。
props.put("key.serializer",
"org.Apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer",
"org.Apache.kafka.common.serialization.StringSerializer");
これが完全ですKafkaプロデューサーの例:-
import Java.util.Properties;
import org.Apache.kafka.clients.producer.Producer;
import org.Apache.kafka.clients.producer.KafkaProducer;
import org.Apache.kafka.clients.producer.ProducerRecord;
public class FxDateProducer {
public static void main(String[] args) throws Exception{
if(args.length == 0){
System.out.println("Enter topic name”);
return;
}
String topicName = args[0].toString();
Properties props = new Properties();
//Assign localhost id
props.put("bootstrap.servers", “localhost:9092");
//Set acknowledgements for producer requests.
props.put("acks", “all");
//If the request fails, the producer can automatically retry,
props.put("retries", 0);
//Specify buffer size in config
props.put("batch.size", 16384);
//Reduce the no of requests less than 0
props.put("linger.ms", 1);
//The buffer.memory controls the total amount of memory available to the producer for buffering.
props.put("buffer.memory", 33554432);
props.put("key.serializer",
"org.Apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer",
"org.Apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new KafkaProducer
<String, String>(props);
for(int i = 0; i < 10; i++)
producer.send(new ProducerRecord<String, String>(topicName,
Integer.toString(i), Integer.toString(i)));
System.out.println(“Message sent successfully”);
producer.close();
}
}
Kafkaバージョンの問題が原因で発生します。正しいkafkaバージョンを使用していることを確認してください。使用したバージョンは 'kafka_2.12-1.0.1'です。
ただし、コードで以下のプロパティを使用してみてください。これで問題が修正されました。
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.Apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.Apache.kafka.common.serialization.StringSerializer");
以前、問題の原因となっている以下のプロパティを使用していました。
//props.put("key.serializer","org.Apache.kafka.common.serialization.Stringserializer");
//props.put("value.serializer","org.Apache.kafka.common.serialization.Stringserializer");