嵌入式 kafka scalatest ClassNotFoundException:scala.collection.GenTraversableOnce

嵌入式 kafka scalatest ClassNotFoundException:scala.collection.GenTraversableOnce

问题描述:

Scala 新手,我正在使用 https://github 实现 ScalaTest 的第一步.com/embeddedkafka/embedded-kafka 根据 README 顶部的第二个示例:

New to Scala, I'm on step one of implementing a ScalaTest with https://github.com/embeddedkafka/embedded-kafka according to the second example at the top of that 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()
    }
  }
}

运行这个测试,失败的程度比我熟悉的要低:

Running this test, the failure is at a lower level than I am familiar with:

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 内容:

I suspect a mismatch of dependency versions, but can't spot it. Here's my relevant build.gradle contents:

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'
}

Gradle 对于 Scala 的传递依赖确实有点有趣 - 从某种意义上说,它不会自动计算一组连贯的版本.

Gradle can indeed be a bit funny with transitive dependencies for Scala - in the sense that it will not automatically calculate a coherent set of versions.

失踪"class scala/collection/GenTraversableOnce 是 scala-library 的一部分,在 2.12.x 中可用

The "missing" class scala/collection/GenTraversableOnce is part of the scala-library and is available in 2.12.x

所以你应该能够通过以下方式解决这个问题:

So you should be able to fix this by:

完成此操作后,假设您的 IDE 设置为与 build.gradle 文件同步,您应该能够查看 gradle 计算的依赖项(声明的和可传递的).如果您仍然有问题,请手动检查这些,看看 org.scala-lang:scala-library 库是否丢失或声明了两次.如果您有多个声明,您可以在 mvncentral.com 中查看每个库的依赖项.

Once you have done this, assuming your IDE is set up to sync with your build.gradle file, you should be able to look at the dependencies (declared and transitive) that gradle has calculated. If you still have problems, go through these manually and see if the org.scala-lang:scala-library library is missing or declared twice. If you have multiple declarations you can look at each library's dependencies in mvncentral.com .

注意步骤 (a) 的原因是您的编译"依赖项中有 Scala 人工制品,因此我假设您的所有代码(不仅仅是您的测试代码)都使用了 Scala.

N.B. the reason for step (a) is that you have scala artefacts in your 'compile' dependencies, so I assume that all your code (not just your test code) is using scala.