java.lang.NoSuchFieldError при использовании ScalaTest
При использовании ScalaTest я получаю довольно сложную для отладки ошибку. Как ни странно, это происходит, когда моя программа не имеет объекта Main, но не когда у нее есть объект Main. Мой код на самом деле просто использует класс типов с полиморфным методом для получения фрагмента из списка и выглядит так (извиняюсь за немного подробный пример, я сократил его, насколько это возможно):
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)
}
}
Мой тест прост и выглядит так, в отдельном файле в тестовом каталоге:
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)
}
}
Если я использую sbt testэтот код как есть, я получаю следующую ошибку:
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)
Затем я попытался добавить в программу класс Main, чтобы узнать, проблема ли это в тесте или проблема в самом коде:
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)
}
Это отлично работает, если я sbt run, и, как ни странно, также позволяет мне работать sbt testбез каких-либо проблем. Если я затем удалю этот основной класс, sbt testснова не удастся. Кто-нибудь может пролить свет на то, что здесь происходит?
Спасибо за любую помощь!
Ответы
На самом деле я запустил Scalatest из командной строки, и это удалось
$ 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.
в то время как в IntelliJ и sbt это не удалось:
(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)
(сбт)
[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
Таким образом, проблема, похоже, заключается в том, как IntelliJ и sbt запускают Scalatest.
NoSuchFieldError Java
Java NoSuchFieldError при использовании Reflection
https://github.com/unicredit/hbase-rdd/issues/21