java.lang.NoSuchFieldError bei Verwendung von ScalaTest

Sep 20 2020

Bei der Verwendung von ScalaTest wird ein ziemlich schwer zu debuggender Fehler angezeigt. Seltsamerweise scheint dies zu geschehen, wenn mein Programm kein Hauptobjekt hat, aber nicht, wenn es ein Hauptobjekt hat. Mein Code verwendet wirklich nur eine Typklasse mit einer polymorphen Methode, um ein Slice aus einer Liste zu erhalten, und sieht folgendermaßen aus (Entschuldigung für das leicht ausführliche Beispiel, ich habe es so weit wie möglich reduziert):

package sportarray

object ArrayDefs {
  abstract class IsArr[A, I0, DT] {
    def getElem(self: A, i: Int): DT
    def getSlice[R](self: A, r: R)(implicit sliceTc: IsSlice[R]): sliceTc.Out = sliceTc.getSlice(self, r)

    trait IsSlice[R] {
      type Out
      def getSlice(self: A, ref: R): Out 
    }
    object IsSlice {
      implicit val iLocTCForInt = new IsSlice[Int] { 
        type Out = DT
        def getSlice(self: A, ref: Int): Out = getElem(self, ref)
      }
      implicit val iLocTCForList = new IsSlice[List[Int]] { 
        type Out = List[DT]
        def getSlice(self: A, ref: List[Int]): Out = ref.map(getElem(self, _))
      }
    }
  }

  object IsArrSyntax {
    implicit class IsArrOps[A, I0, T](self: A)(implicit 
      tc1d: IsArr[A, I0, T]
    ) {
      def getElem(i: Int) = tc1d.getElem(self, i)
      def getSlice[R](r: R)(implicit sliceTc: tc1d.IsSlice[R]) = tc1d.getSlice(self, r)
    }
  }
}

object ListOfListsObj {
  import ArrayDefs._
  case class List1d[I0, T] (
    indices: List[I0],
    data: List[T],
  )
  implicit def list1dIs1dSpArr[A, I0, T] = 
    new IsArr[List1d[I0, T], I0, T] {
      def getElem(self: List1d[I0, T], i: Int) = self.data(i)
    }
}

Mein Test ist einfach und sieht so aus, in einer eigenen Datei im Testverzeichnis:

package sportarray

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class ArraySpec extends AnyFlatSpec with Matchers {
  "List" should "act as an array" in {
    import ArrayDefs._
    import ArrayDefs.IsArrSyntax._
    import ListOfListsObj._
    val list1d = List1d[Int, Double](List(1,2,3), List(1.0, 2.0, 3.0))
    assert(list1d.getSlice(1) == 2.0)
  }
}

Wenn ich sbt testdiesen Code so wie er ist, erhalte ich den folgenden Fehler:

java.lang.NoSuchFieldError: sportarray$ArrayDefs$IsArrSyntax$IsArrOps$$tc1d
at sportarray.ArraySpec.$anonfun$new$1(HelloSpec.scala:12) 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.flatspec.AnyFlatSpecLike$$anon$5.apply(AnyFlatSpecLike.scala:1683)

Ich habe dann versucht, dem Programm eine Hauptklasse hinzuzufügen, um festzustellen, ob dies ein Problem mit dem Test oder ein Problem mit dem Code selbst war:

object Main extends App {
  import ArrayDefs._
  import ArrayDefs.IsArrSyntax._
  import ListOfListsObj._
  val list1d = List1d[Int, Double](List(1,2,3), List(1.0, 2.0, 3.0))
  assert(list1d.getSlice(1) == 2.0)
}

Dies funktioniert gut, wenn ich sbt runund seltsamerweise auch sbt testohne Probleme laufen kann. Wenn ich dann diese Hauptklasse lösche, sbt testschlägt dies erneut fehl. Kann jemand Licht ins Dunkel bringen, was hier vor sich geht?

Vielen Dank für jede Hilfe!

Antworten

2 DmytroMitin Sep 21 2020 at 21:03

Eigentlich Ich lief Scalatest von der Kommandozeile und es succeded

$ scalac -cp .:scalactic_2.13-3.2.2.jar:scalatest_2.13-3.2.2.jar:scalatest-core_2.13-3.2.2.jar:scalatest-flatspec_2.13-3.2.2.jar:scalatest-matchers-core_2.13-3.2.2.jar:scalatest-shouldmatchers_2.13-3.2.2.jar:scalatest-compatible-3.2.2.jar App.scala AppTest.scala $ scala -cp .:scalactic_2.13-3.2.2.jar:scalatest_2.13-3.2.2.jar:scalatest-core_2.13-3.2.2.jar:scalatest-flatspec_2.13-3.2.2.jar:scalatest-matchers-core_2.13-3.2.2.jar:scalatest-shouldmatchers_2.13-3.2.2.jar:scalatest-compatible-3.2.2.jar:scala-xml_2.13-1.3.0.jar org.scalatest.run AppTest
Run starting. Expected test count is: 1
AppTest:
List
- should act as an array
Run completed in 151 milliseconds.
Total number of tests run: 1
Suites: completed 1, aborted 0
Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
All tests passed.

während in IntelliJ und sbt es fehlgeschlagen ist:

(IntelliJ)

An exception or error caused a run to abort: App$ArrayDefs$IsArrSyntax$IsArrOps$$tc1d
java.lang.NoSuchFieldError: App$ArrayDefs$IsArrSyntax$IsArrOps$$tc1d
    at AppTest.$anonfun$new$1(AppTest.scala:10) 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.flatspec.AnyFlatSpecLike$$anon$5.apply(AnyFlatSpecLike.scala:1683) at org.scalatest.TestSuite.withFixture(TestSuite.scala:196) at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
    at org.scalatest.flatspec.AnyFlatSpec.withFixture(AnyFlatSpec.scala:1685)
    at org.scalatest.flatspec.AnyFlatSpecLike.invokeWithFixture$1(AnyFlatSpecLike.scala:1681) at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$runTest$1(AnyFlatSpecLike.scala:1693)
    at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
    at org.scalatest.flatspec.AnyFlatSpecLike.runTest(AnyFlatSpecLike.scala:1693)
    at org.scalatest.flatspec.AnyFlatSpecLike.runTest$(AnyFlatSpecLike.scala:1675) at org.scalatest.flatspec.AnyFlatSpec.runTest(AnyFlatSpec.scala:1685) at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$runTests$1(AnyFlatSpecLike.scala:1751)
    at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:413) at scala.collection.immutable.List.foreach(List.scala:333) at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
    at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:390)
    at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:427) at scala.collection.immutable.List.foreach(List.scala:333) at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
    at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:396)
    at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:475)
    at org.scalatest.flatspec.AnyFlatSpecLike.runTests(AnyFlatSpecLike.scala:1751)
    at org.scalatest.flatspec.AnyFlatSpecLike.runTests$(AnyFlatSpecLike.scala:1750) at org.scalatest.flatspec.AnyFlatSpec.runTests(AnyFlatSpec.scala:1685) at org.scalatest.Suite.run(Suite.scala:1112) at org.scalatest.Suite.run$(Suite.scala:1094)
    at org.scalatest.flatspec.AnyFlatSpec.org$scalatest$flatspec$AnyFlatSpecLike$$super$run(AnyFlatSpec.scala:1685) at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$run$1(AnyFlatSpecLike.scala:1796)
    at org.scalatest.SuperEngine.runImpl(Engine.scala:535)
    at org.scalatest.flatspec.AnyFlatSpecLike.run(AnyFlatSpecLike.scala:1796)
    at org.scalatest.flatspec.AnyFlatSpecLike.run$(AnyFlatSpecLike.scala:1794) at org.scalatest.flatspec.AnyFlatSpec.run(AnyFlatSpec.scala:1685) at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45) at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13(Runner.scala:1320) at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13$adapted(Runner.scala:1314)
    at scala.collection.immutable.List.foreach(List.scala:333)
    at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1314) at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24(Runner.scala:993) at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24$adapted(Runner.scala:971)
    at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1480) at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:971)
    at org.scalatest.tools.Runner$.run(Runner.scala:798)
    at org.scalatest.tools.Runner.run(Runner.scala)
    at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2or3(ScalaTestRunner.java:40)
    at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:27)

(sbt)

[error] java.lang.NoSuchFieldError: App$ArrayDefs$IsArrSyntax$IsArrOps$$tc1d [error] at AppTest.$anonfun$new$1(AppTest.scala:10)
[error]     at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
[error]     at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83) [error] at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[error]     at org.scalatest.Transformer.apply(Transformer.scala:22)
[error]     at org.scalatest.Transformer.apply(Transformer.scala:20)
[error]     at org.scalatest.flatspec.AnyFlatSpecLike$$anon$5.apply(AnyFlatSpecLike.scala:1683)
[error]     at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
[error]     at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195) [error] at org.scalatest.flatspec.AnyFlatSpec.withFixture(AnyFlatSpec.scala:1685) [error] at org.scalatest.flatspec.AnyFlatSpecLike.invokeWithFixture$1(AnyFlatSpecLike.scala:1681)
[error]     at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$runTest$1(AnyFlatSpecLike.scala:1693) [error] at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306) [error] at org.scalatest.flatspec.AnyFlatSpecLike.runTest(AnyFlatSpecLike.scala:1693) [error] at org.scalatest.flatspec.AnyFlatSpecLike.runTest$(AnyFlatSpecLike.scala:1675)
[error]     at org.scalatest.flatspec.AnyFlatSpec.runTest(AnyFlatSpec.scala:1685)
[error]     at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$runTests$1(AnyFlatSpecLike.scala:1751) [error] at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:413)
[error]     at scala.collection.immutable.List.foreach(List.scala:333)
[error]     at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401) [error] at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:390) [error] at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:427)
[error]     at scala.collection.immutable.List.foreach(List.scala:333)
[error]     at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401) [error] at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:396) [error] at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:475) [error] at org.scalatest.flatspec.AnyFlatSpecLike.runTests(AnyFlatSpecLike.scala:1751) [error] at org.scalatest.flatspec.AnyFlatSpecLike.runTests$(AnyFlatSpecLike.scala:1750)
[error]     at org.scalatest.flatspec.AnyFlatSpec.runTests(AnyFlatSpec.scala:1685)
[error]     at org.scalatest.Suite.run(Suite.scala:1112)
[error]     at org.scalatest.Suite.run$(Suite.scala:1094) [error] at org.scalatest.flatspec.AnyFlatSpec.org$scalatest$flatspec$AnyFlatSpecLike$$super$run(AnyFlatSpec.scala:1685)
[error]     at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$run$1(AnyFlatSpecLike.scala:1796) [error] at org.scalatest.SuperEngine.runImpl(Engine.scala:535) [error] at org.scalatest.flatspec.AnyFlatSpecLike.run(AnyFlatSpecLike.scala:1796) [error] at org.scalatest.flatspec.AnyFlatSpecLike.run$(AnyFlatSpecLike.scala:1794)
[error]     at org.scalatest.flatspec.AnyFlatSpec.run(AnyFlatSpec.scala:1685)
[error]     at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:318)
[error]     at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:513) [error] at sbt.TestRunner.runTest$1(TestFramework.scala:139)
[error]     at sbt.TestRunner.run(TestFramework.scala:154)
[error]     at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.$anonfun$apply$1(TestFramework.scala:317) [error] at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:277)
[error]     at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.apply(TestFramework.scala:317)
[error]     at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.apply(TestFramework.scala:317)
[error]     at sbt.TestFunction.apply(TestFramework.scala:329)
[error]     at sbt.Tests$.$anonfun$toTask$1(Tests.scala:311)
[error]     at sbt.std.Transform$$anon$3.$anonfun$apply$2(Transform.scala:46) [error] at sbt.std.Transform$$anon$4.work(Transform.scala:67) [error] at sbt.Execute.$anonfun$submit$2(Execute.scala:281)
[error]     at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19) [error] at sbt.Execute.work(Execute.scala:290) [error] at sbt.Execute.$anonfun$submit$1(Execute.scala:281)
[error]     at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178) [error] at sbt.CompletionService$$anon$2.call(CompletionService.scala:37) [error] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [error] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error]     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [error] at java.lang.Thread.run(Thread.java:748) [error] (Test / executeTests) java.lang.NoSuchFieldError: App$ArrayDefs$IsArrSyntax$IsArrOps$$tc1d

Das Problem scheint also zu sein, wie IntelliJ und sbt Scalatest ausführen.

NoSuchFieldError Java

Java NoSuchFieldError bei Verwendung von Reflection

https://github.com/unicredit/hbase-rdd/issues/21