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

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

问题描述:

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

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

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

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.

丢失"scala/collection/GenTraversableOnce类是scala库的一部分,在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.