встроенная кафка scalatest ClassNotFoundException: scala.collection.GenTraversableOnce

Новичок в Scala, я нахожусь на первом этапе реализации ScalaTest с помощью https://github.com/embeddedkafka/embedded-kafka согласно второму примеру вверху этого README:

import net.manub.embeddedkafka.EmbeddedKafka
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike

class MinimalTest extends AnyWordSpecLike with Matchers {

  "runs with embedded kafka" should {

    "work" in {
      EmbeddedKafka.start()

      1 + 1 shouldBe 2
      // ... code goes here

      EmbeddedKafka.stop()
    }
  }
}

При выполнении этого теста сбой находится на более низком уровне, чем я знаком:

MinimalTest:
runs with embedded kafka
*** RUN ABORTED ***
  java.lang.NoClassDefFoundError: scala/collection/GenTraversableOnce
  at com.myorganization.api.MinimalTest.$anonfun$new$2(MinimalTest.scala:13)
  at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
  at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
  at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
  at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
  at org.scalatest.Transformer.apply(Transformer.scala:22)
  at org.scalatest.Transformer.apply(Transformer.scala:20)
  at org.scalatest.wordspec.AnyWordSpecLike$$anon$3.apply(AnyWordSpecLike.scala:1076)
  at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
  at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
  ...
  Cause: java.lang.ClassNotFoundException: scala.collection.GenTraversableOnce
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
  at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
  at com.myorganization.api.MinimalTest.$anonfun$new$2(MinimalTest.scala:13)
  at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
  at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
  at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
  at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
  at org.scalatest.Transformer.apply(Transformer.scala:22)
  at org.scalatest.Transformer.apply(Transformer.scala:20)
  ...

Я подозреваю несоответствие версий зависимостей, но не могу его обнаружить. Вот мое соответствующее содержимое build.gradle:

plugins {
    id 'java'
    id 'scala'
}

task spec(dependsOn: ['testClasses'], type: JavaExec) {
    main = 'org.scalatest.tools.Runner'
    args = ['-R', 'build/classes/scala/test', '-o']
    classpath = sourceSets.test.runtimeClasspath
}

dependencies {
    compile 'io.confluent:kafka-streams-avro-serde:5.4.0'
    compile 'io.github.embeddedkafka:embedded-kafka-streams_2.12:2.4.0'
    compile 'io.github.embeddedkafka:embedded-kafka_2.12:2.4.0'
    compile 'org.apache.avro:avro:1.9.1'
    compile 'org.apache.kafka:kafka-clients:2.4.0'
    compile 'org.apache.kafka:kafka-streams:2.4.0'
    compile 'org.apache.kafka:kafka_2.13:2.4.0'
    compile 'org.scala-lang:scala-reflect:2.12.6'
    testCompile 'io.github.embeddedkafka:embedded-kafka-schema-registry_2.12:5.4.0' // match schema registry version
    testCompile 'io.github.embeddedkafka:embedded-kafka-streams_2.13:2.4.0' // match kafka streams version
    testCompile 'io.github.embeddedkafka:embedded-kafka_2.13:2.4.0' // match kafka version
    testCompile 'org.scala-lang:scala-library:2.13.2'
    testCompile 'org.scalatest:scalatest_2.13:3.1.2'
    testImplementation 'junit:junit:4.11'
    testRuntime 'org.pegdown:pegdown:1.4.2'
}


person Charney Kaye    schedule 12.06.2020    source источник
comment
scala-reflect 2.13.2 вместо 2.12.6? И еще одна вещь: в вашем тестовом примере используйте beforeandafterall из scalatest   -  person Shankar Shastri    schedule 12.06.2020
comment
Благодарю вас! Большая ошибка... 2.13 в org.apache.kafka:kafka_2.13:2.4.0 означает Scala 2.13. Поэтому все они должны были быть обновлены до 2.12.   -  person Charney Kaye    schedule 12.06.2020


Ответы (1)


Gradle действительно может быть немного забавным с транзитивными зависимостями для Scala — в том смысле, что он не будет автоматически вычислять согласованный набор версий.

Отсутствующий класс scala/collection/GenTraversableOnce является частью библиотеки scala и доступен в версии 2.12.x.

Итак, вы должны быть в состоянии исправить это:

  • а. Явное объявление версии библиотеки scala в вашем пути к классам среды выполнения: implementation group: 'org.scala-lang', name: 'scala-library', version: '2.12.6'
  • б. Проверка всех ваших других зависимостей на версии 2.13 библиотек (как предложил @ShankarShastri). Похоже, что у embedded-kafka есть сборка, совместимая с 2.12: https://mvnrepository.com/artifact/io.github.embeddedkafka/embedded-kafka_2.12/2.5.0

После того, как вы это сделаете, предполагая, что ваша IDE настроена на синхронизацию с вашим файлом build.gradle, вы сможете просмотреть зависимости (объявленные и транзитивные), рассчитанные gradle. Если у вас все еще есть проблемы, просмотрите их вручную и посмотрите, отсутствует ли библиотека org.scala-lang:scala-library или объявлена ​​ли она дважды. Если у вас есть несколько объявлений, вы можете посмотреть зависимости каждой библиотеки на mvncentral.com.

Н.Б. причина для шага (a) заключается в том, что у вас есть артефакты scala в ваших зависимостях «компиляции», поэтому я предполагаю, что весь ваш код (а не только ваш тестовый код) использует scala.

person marracuene    schedule 19.07.2020