Я пытаюсь интегрировать встроенную кафку в scala 2.11 для своих тестов. Однако я получаю следующую ошибку, которую я не мог понять.
java.lang.NoClassDefFoundError: org/apache/zookeeper/AsyncCallback$MultiCallback
Все версии библиотек kafka одинаковы. Не могли бы вы сказать, что не так в моем коде?
Вот мои зависимости
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql-kafka-0-10_2.11</artifactId>
<version>2.4.7</version>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.github.embeddedkafka</groupId>
<artifactId>embedded-kafka_2.11</artifactId>
<version>2.4.0</version>
<scope>test</scope>
</dependency>
Вот как я запускаю/останавливаю встроенный сервер kafka.
implicit val embedKafkaConfig = EmbeddedKafkaConfig(kafkaPort = 7000, zooKeeperPort = 7001)
implicit val stringDeserializer = new StringDeserializer()
implicit val stringSerializer = new StringSerializer
Before("") { _: Scenario =>
EmbeddedKafka.start()(embedKafkaConfig)
}
After("") { _: Scenario =>
EmbeddedKafka.stop()
}
И ошибка:
kafka.server.KafkaServer - Fatal error during KafkaServer startup. Prepare to shutdown
java.lang.NoClassDefFoundError: org/apache/zookeeper/AsyncCallback$MultiCallback
at kafka.zk.KafkaZkClient$.apply(KafkaZkClient.scala:1857)
at kafka.server.KafkaServer.kafka$server$KafkaServer$$createZkClient$1(KafkaServer.scala:374)
at kafka.server.KafkaServer.initZkClient(KafkaServer.scala:399)
at kafka.server.KafkaServer.startup(KafkaServer.scala:207)
at net.manub.embeddedkafka.ops.KafkaOps$class.startKafka(kafkaOps.scala:52)
at net.manub.embeddedkafka.EmbeddedKafka$.startKafka(EmbeddedKafka.scala:50)
at net.manub.embeddedkafka.ops.KafkaOps$class.startKafka(kafkaOps.scala:60)
at net.manub.embeddedkafka.EmbeddedKafka$.startKafka(EmbeddedKafka.scala:50)
at net.manub.embeddedkafka.ops.RunningKafkaOps$class.startKafka(kafkaOps.scala:88)
at net.manub.embeddedkafka.EmbeddedKafka$.startKafka(EmbeddedKafka.scala:50)
at net.manub.embeddedkafka.EmbeddedKafka$.start(EmbeddedKafka.scala:68)
Я думаю, что аналогичная проблема уже сообщалась здесь из-за некоторых конфликтующих версий между версиями зависимостей Kafk и zookeeper, о которых сообщалось в старых проблемах Apache.
https://issues.apache.org/jira/browse/BIGTOP-3208
https://github.com/apache/bigtop/pull/536
Я предлагаю вам создать дерево зависимостей и проверить совместимость версий, чтобы решить проблемы с версиями.
Спасибо за Ваш ответ. Я добавил дерево dep в свой пост. Как я могу переопределить zookeper 3.4.6 с 3.5.6 в области тестирования?
@gabby Смотрите возможный ответ в конце моего ответа
@gabby Я думаю, вы могли бы сначала проверить выпущенную версию зависимости встроенной kafka, которая содержит zookeper 3.4.6 для области тестирования. В противном случае попробуйте исключить зависимость zoo-keeper 3.5.6 от kafka-2.4.0. (Пожалуйста, посмотрите аналогичные правила исключения в примерах sbt: stackoverflow.com/questions/10958215/… ) и посмотрите, выбирает ли он старый. Я также проверил проект. github.com/embeddedkafka/embedded-kafka/blob/v2.4.0/build.sbt и github.com/apache/kafka/blob/2.4.0/build.gradle
Интерфейс org.apache.zookeeper.AsyncCallback.MultiCallback
появился в Zookeeper 3.4.7+
Отсутствовал в Zookeeper 3.4.6-
Судя по предоставленной вами части pom.xml
, вы используете Zookeeper 3.5.6, и это должно быть нормально.
Вы должны проверить, использует ли какая-либо зависимость Zookeeper 3.4.6- в вашем реальном случае использования.
Подозреваю, что вы предоставили недостаточно информации для воспроизведения. Я не могу воспроизвести. https://scastie.scala-lang.org/DmytroMitin/q4BRo4taQAey47JufBc87w/1 (см. также вкладку «Настройки сборки»). Как создать минимальный воспроизводимый пример. Проверить себя можно следующим образом. Создайте пустой проект с вашим файлом сборки и вашим кодом. Если вы не можете воспроизвести там поведение, то и мы не сможем.
Общие причины NoClassDefFoundError
:
Почему я получаю ошибку NoClassDefFoundError в Java?
Какие причины и в чем разница между NoClassDefFoundError и ClassNotFoundException?
NoClassDefFoundError
может сигнализировать о несовместимости в зависимостях
Невозможно записать DF в дельта-формате на hdfs
ClassNotFoundException: breeze.storage.Zero$DoubleZero$
Как исправить внедрение зависимостей при обновлении игровой среды с 2.5.x до 2.6.x Scala
sbt dependencyTree
. В Maven это должно быть похоже на mvn dependency:tree
с maven-dependency-plugin (но в sbt это не показывает provided
зависимости)Как получить дерево зависимостей для артефакта?
Или напечатайте System.getProperty("java.class.path")
(но это показывает путь к классам только при запуске JVM).
Или добавьте scalacOptions += "-Ylog-classpath"
к build.sbt
. В maven это должно быть похоже на <arg>-Ylog-classpath</arg>
Указание параметра времени компиляции Scalac с помощью maven-scala-plugin
var cl = getClass.getClassLoader
while (cl != null) {
println(s"classloader: ${cl.getClass.getName}")
cl match {
case cl: URLClassLoader =>
println("classloader urls:")
cl.getURLs.foreach(println)
case _ =>
println("not URLClassLoader")
}
cl = cl.getParent
}
Судя по той части дерева зависимостей, которую вы разместили, для воспроизведения достаточно было добавить
<dependencies>
...
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.4.7</version>
<scope>provided</scope>
</dependency>
</dependencies>
Как я могу переопределить zookeper 3.4.6 с 3.5.6 в области тестирования?
Попробуйте добавить в pom.xml
<dependencies>
...
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.6</version>
<scope>test</scope>
</dependency>
</dependencies>
Как форсировать конкретную версию зависимости? (сбт)
Maven: как переопределить зависимость, добавленную библиотекой (maven)
Зачем предоставлять кучу сообщений NoClassDef, которые не имеют ничего общего с классом, упомянутым в сообщении? Breeze, Scala Collections, Play и т. д. никогда не упоминаются в вопросе.
@OneCricketeer Они иллюстрируют, как я исследовал проблемы с NoClassDefFoundError
в разных случаях. Причины NoClassDefFoundError
могут быть разными в разных случаях. Но подходы к исследованию причин схожи. Вы согласны?
«Предоставленная» область означает, что она не скомпилирована в ваш код. Поэтому тесты его не найдут