mockito/mockito-scala

Mockito and Swagger - unsafe symbol ApiModelProperty (child of package annotations) in runtime reflection universe

kwhitehouse opened this issue · 0 comments

One-line description of issue: We're seeing java.lang.AssertionError: unsafe symbol ApiModelProperty (child of package annotations) in runtime reflection universe and believe it's related to an interaction between mockito and swagger.

Dependencies

Below is a snippet of the versions we're using of a few libraries that might be relevant.

"org.scalatest"  %% "scalatest" % ScalaTestVersion % Test,
"org.scalatestplus" %% "mockito-4-5" % "3.2.12.0" % Test,
"org.mockito" % "mockito-inline" % "2.13.0" % Test,
"org.mockito" %% "mockito-scala-scalatest" % "1.17.0" % Test,
"com.github.swagger-akka-http" %% "swagger-akka-http"   % "1.4.0",

Code snippet

I was able to reproduce with the simple code snippet below.

package mypackage

import com.myclient.ClientThatUsesSwagger

import org.scalatest.freespec.AsyncFreeSpec
import org.scalatest.matchers.should.Matchers
import org.mockito.scalatest.AsyncMockitoSugar


class MySpec extends AsyncFreeSpec with Matchers with AsyncMockitoSugar {
   val myMock     = mock[ClientThatUsesSwagger]
}

The mocked ClientThatUsesSwagger is a client that has a method with a parameter type that is annotated with the Swagger annotation @ApiModelProperty, like so. Note that I didn't go as far as to reproduce using these code snippets, though if I have time later this week I can do that.

package anotherpackage

import scala.concurrent.Future

trait ClientThatUsesSwagger {

  def includesParameterAnnotatedWithSwagger(obj: MyObject): Boolean = {
       ...
  }
}
package anotherpackage

import io.circe.generic.extras.{Configuration, ConfiguredJsonCodec}
import io.swagger.annotations.ApiModelProperty

import scala.annotation.meta.field

object MyObject {
  implicit val config: Configuration = Configuration.default.withSnakeCaseMemberNames
}

@ConfiguredJsonCodec final case class MyObject(
  @(ApiModelProperty @field)(name = "some_field", value = "Some value.", dataType = "string")
  someField: Option[String]
)

Notable Details

When we switch from using AsyncMockitoSugar to MockitoSugar this AssertionError disappears.

Stack Trace

java.lang.AssertionError: unsafe symbol ApiModelProperty (child of package annotations) in runtime reflection universe
  | => pat scala.reflect.internal.Symbols$Symbol.<init>(Symbols.scala:232)
	at scala.reflect.internal.Symbols$TypeSymbol.<init>(Symbols.scala:3153)
	at scala.reflect.internal.Symbols$ClassSymbol.<init>(Symbols.scala:3339)
	at scala.reflect.internal.Symbols$StubClassSymbol.<init>(Symbols.scala:3618)
	at scala.reflect.internal.Symbols.newStubSymbol(Symbols.scala:215)
	at scala.reflect.internal.Symbols.newStubSymbol$(Symbols.scala:211)
	at scala.reflect.internal.SymbolTable.newStubSymbol(SymbolTable.scala:28)
	at scala.reflect.internal.Symbols$Symbol.newStubSymbol(Symbols.scala:535)
	at scala.reflect.internal.pickling.UnPickler$Scan.$anonfun$readSymbol$6(UnPickler.scala:266)
	at scala.reflect.internal.pickling.UnPickler$Scan.$anonfun$readSymbol$5(UnPickler.scala:253)
	at scala.reflect.internal.pickling.UnPickler$Scan.$anonfun$readSymbol$4(UnPickler.scala:253)
	at scala.reflect.internal.pickling.UnPickler$Scan.readExtSymbol$1(UnPickler.scala:251)
	at scala.reflect.internal.pickling.UnPickler$Scan.readSymbol(UnPickler.scala:274)
	at scala.reflect.internal.pickling.UnPickler$Scan.readSymbolRef(UnPickler.scala:645)
	at scala.reflect.internal.pickling.UnPickler$Scan.readType(UnPickler.scala:412)
	at scala.reflect.internal.pickling.UnPickler$Scan.$anonfun$readTypeRef$1(UnPickler.scala:654)
	at scala.reflect.internal.pickling.UnPickler$Scan.at(UnPickler.scala:180)
	at scala.reflect.internal.pickling.UnPickler$Scan.readTypeRef(UnPickler.scala:654)
	at scala.reflect.internal.pickling.UnPickler$Scan.readType(UnPickler.scala:418)
	at scala.reflect.internal.pickling.UnPickler$Scan.$anonfun$readTypeRef$1(UnPickler.scala:654)
	at scala.reflect.internal.pickling.UnPickler$Scan.at(UnPickler.scala:180)
	at scala.reflect.internal.pickling.UnPickler$Scan.readTypeRef(UnPickler.scala:654)
	at scala.reflect.internal.pickling.UnPickler$Scan.readAnnotationInfo(UnPickler.scala:488)
	at scala.reflect.internal.pickling.UnPickler$Scan.readSymbolAnnotation(UnPickler.scala:511)
	at scala.reflect.internal.pickling.UnPickler$Scan.run(UnPickler.scala:103)
	at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:44)
	at scala.reflect.runtime.JavaMirrors$JavaMirror.unpickleClass(JavaMirrors.scala:675)
	at scala.reflect.runtime.SymbolLoaders$TopClassCompleter.$anonfun$complete$3(SymbolLoaders.scala:37)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
	at scala.reflect.internal.SymbolTable.slowButSafeEnteringPhaseNotLaterThan(SymbolTable.scala:320)
	at scala.reflect.runtime.SymbolLoaders$TopClassCompleter.complete(SymbolLoaders.scala:34)
	at scala.reflect.runtime.SymbolLoaders$TopClassCompleter.load(SymbolLoaders.scala:42)
	at scala.reflect.runtime.SynchronizedSymbols$SynchronizedSymbol.completeTypeParams$1(SynchronizedSymbols.scala:173)
	at scala.reflect.runtime.SynchronizedSymbols$SynchronizedSymbol.$anonfun$typeParams$1(SynchronizedSymbols.scala:180)
	at scala.reflect.runtime.SynchronizedSymbols$SynchronizedSymbol.typeParams(SynchronizedSymbols.scala:149)
	at scala.reflect.runtime.SynchronizedSymbols$SynchronizedSymbol.typeParams$(SynchronizedSymbols.scala:165)
	at scala.reflect.runtime.SynchronizedSymbols$SynchronizedSymbol$$anon$7.typeParams(SynchronizedSymbols.scala:203)
	at scala.reflect.internal.Types$NoArgsTypeRef.typeParams(Types.scala:2174)
	at scala.reflect.internal.Definitions$DefinitionsClass.fullyInitializeType(Definitions.scala:239)
	at scala.reflect.internal.Types$Type.toString(Types.scala:949)
	at org.mockito.ReflectionUtils$$anonfun$$nestedInanonfun$methodsWithLazyOrVarArgs$2$1$$anonfun$applyOrElse$1.applyOrElse(ReflectionUtils.scala:114)
	at org.mockito.ReflectionUtils$$anonfun$$nestedInanonfun$methodsWithLazyOrVarArgs$2$1$$anonfun$applyOrElse$1.applyOrElse(ReflectionUtils.scala:113)
	at scala.collection.immutable.List.collect(List.scala:267)
	at org.mockito.ReflectionUtils$$anonfun$$nestedInanonfun$methodsWithLazyOrVarArgs$2$1.applyOrElse(ReflectionUtils.scala:113)
	at org.mockito.ReflectionUtils$$anonfun$$nestedInanonfun$methodsWithLazyOrVarArgs$2$1.applyOrElse(ReflectionUtils.scala:111)
	at scala.collection.Iterator$$anon$7.hasNext(Iterator.scala:516)
	at scala.collection.immutable.List.prependedAll(List.scala:155)
	at scala.collection.immutable.List$.from(List.scala:684)
	at scala.collection.immutable.List$.from(List.scala:681)
	at scala.collection.IterableFactory$Delegate.from(Factory.scala:288)
	at scala.collection.immutable.Iterable$.from(Iterable.scala:35)
	at scala.collection.immutable.Iterable$.from(Iterable.scala:32)
	at scala.collection.IterableFactory$Delegate.from(Factory.scala:288)
	at scala.collection.IterableOps.collect(Iterable.scala:678)
	at scala.collection.IterableOps.collect$(Iterable.scala:677)
	at scala.collection.AbstractIterable.collect(Iterable.scala:919)
	at org.mockito.ReflectionUtils$.$anonfun$methodsWithLazyOrVarArgs$2(ReflectionUtils.scala:111)
	at scala.util.Try$.apply(Try.scala:210)
	at org.mockito.ReflectionUtils$.$anonfun$methodsWithLazyOrVarArgs$1(ReflectionUtils.scala:121)
	at scala.collection.immutable.List.flatMap(List.scala:293)
	at scala.collection.immutable.List.flatMap(List.scala:79)
	at org.mockito.ReflectionUtils$.methodsWithLazyOrVarArgs(ReflectionUtils.scala:104)
	at org.mockito.internal.handler.ScalaMockHandler$.apply(ScalaMockHandler.scala:97)
	at org.mockito.MockitoEnhancer.$anonfun$createMock$default$2$1(MockitoAPI.scala:497)
	at org.mockito.MockitoEnhancer.createMock$1(MockitoAPI.scala:513)
	at org.mockito.MockitoEnhancer.createMock(MockitoAPI.scala:522)
	at org.mockito.MockitoEnhancer.mock(MockitoAPI.scala:467)
	at org.mockito.MockitoEnhancer.mock$(MockitoAPI.scala:466)
        ... <line obfuscated> ...
        ... <line obfuscated> ...
	at org.scalatest.freespec.AsyncFreeSpecLike.transformToOutcomeParam$1(AsyncFreeSpecLike.scala:158)
	at org.scalatest.freespec.AsyncFreeSpecLike.$anonfun$registerTestToRun$1(AsyncFreeSpecLike.scala:159)
	at org.scalatest.AsyncTestSuite.$anonfun$transformToOutcome$1(AsyncTestSuite.scala:240)
	at org.scalatest.freespec.AsyncFreeSpecLike$$anon$1.apply(AsyncFreeSpecLike.scala:431)
	at org.scalatest.AsyncTestSuite.withFixture(AsyncTestSuite.scala:316)
	at org.scalatest.AsyncTestSuite.withFixture$(AsyncTestSuite.scala:315)
        ... <line obfuscated> ...
	at org.mockito.scalatest.MockitoSessionAsyncFixture.withFixture(MockitoSessionFixture.scala:34)
	at org.mockito.scalatest.MockitoSessionAsyncFixture.withFixture$(MockitoSessionFixture.scala:30)
        ... <line obfuscated> ...
	at org.scalatest.freespec.AsyncFreeSpecLike.invokeWithAsyncFixture$1(AsyncFreeSpecLike.scala:429)
	at org.scalatest.freespec.AsyncFreeSpecLike.$anonfun$runTest$1(AsyncFreeSpecLike.scala:443)
	at org.scalatest.AsyncSuperEngine.runTestImpl(AsyncEngine.scala:374)
	at org.scalatest.freespec.AsyncFreeSpecLike.runTest(AsyncFreeSpecLike.scala:443)
	at org.scalatest.freespec.AsyncFreeSpecLike.runTest$(AsyncFreeSpecLike.scala:423)
	at org.scalatest.freespec.AsyncFreeSpec.runTest(AsyncFreeSpec.scala:2280)
	at org.scalatest.freespec.AsyncFreeSpecLike.$anonfun$runTests$1(AsyncFreeSpecLike.scala:502)
	at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$3(AsyncEngine.scala:435)
	at org.scalatest.Status.$anonfun$thenRun$1(Status.scala:227)
	at org.scalatest.Status.$anonfun$thenRun$1$adapted(Status.scala:225)
	at org.scalatest.ScalaTestStatefulStatus.whenCompleted(Status.scala:648)
	at org.scalatest.Status.thenRun(Status.scala:225)
	at org.scalatest.Status.thenRun$(Status.scala:220)
	at org.scalatest.ScalaTestStatefulStatus.thenRun(Status.scala:511)
	at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$1(AsyncEngine.scala:435)
	at scala.collection.LinearSeqOps.foldLeft(LinearSeq.scala:169)
	at scala.collection.LinearSeqOps.foldLeft$(LinearSeq.scala:165)
	at scala.collection.immutable.List.foldLeft(List.scala:79)
	at org.scalatest.AsyncSuperEngine.traverseSubNodes$1(AsyncEngine.scala:406)
	at org.scalatest.AsyncSuperEngine.runTestsInBranch(AsyncEngine.scala:479)
	at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$4(AsyncEngine.scala:463)
	at org.scalatest.Status.$anonfun$thenRun$1(Status.scala:227)
	at org.scalatest.Status.$anonfun$thenRun$1$adapted(Status.scala:225)
	at org.scalatest.ScalaTestStatefulStatus.whenCompleted(Status.scala:648)
	at org.scalatest.Status.thenRun(Status.scala:225)
	at org.scalatest.Status.thenRun$(Status.scala:220)
	at org.scalatest.ScalaTestStatefulStatus.thenRun(Status.scala:511)
	at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$1(AsyncEngine.scala:463)
	at scala.collection.LinearSeqOps.foldLeft(LinearSeq.scala:169)
	at scala.collection.LinearSeqOps.foldLeft$(LinearSeq.scala:165)
	at scala.collection.immutable.List.foldLeft(List.scala:79)
	at org.scalatest.AsyncSuperEngine.traverseSubNodes$1(AsyncEngine.scala:406)
	at org.scalatest.AsyncSuperEngine.runTestsInBranch(AsyncEngine.scala:479)
	at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$1(AsyncEngine.scala:460)
	at scala.collection.LinearSeqOps.foldLeft(LinearSeq.scala:169)
	at scala.collection.LinearSeqOps.foldLeft$(LinearSeq.scala:165)
	at scala.collection.immutable.List.foldLeft(List.scala:79)
	at org.scalatest.AsyncSuperEngine.traverseSubNodes$1(AsyncEngine.scala:406)
	at org.scalatest.AsyncSuperEngine.runTestsInBranch(AsyncEngine.scala:487)
	at org.scalatest.AsyncSuperEngine.runTestsImpl(AsyncEngine.scala:555)
	at org.scalatest.freespec.AsyncFreeSpecLike.runTests(AsyncFreeSpecLike.scala:502)
	at org.scalatest.freespec.AsyncFreeSpecLike.runTests$(AsyncFreeSpecLike.scala:501)
	at org.scalatest.freespec.AsyncFreeSpec.runTests(AsyncFreeSpec.scala:2280)
	at org.scalatest.Suite.run(Suite.scala:1114)
	at org.scalatest.Suite.run$(Suite.scala:1096)
	at org.scalatest.freespec.AsyncFreeSpec.org$scalatest$freespec$AsyncFreeSpecLike$$super$run(AsyncFreeSpec.scala:2280)
	at org.scalatest.freespec.AsyncFreeSpecLike.$anonfun$run$1(AsyncFreeSpecLike.scala:546)
	at org.scalatest.AsyncSuperEngine.runImpl(AsyncEngine.scala:625)
	at org.scalatest.freespec.AsyncFreeSpecLike.run(AsyncFreeSpecLike.scala:546)
	at org.scalatest.freespec.AsyncFreeSpecLike.run$(AsyncFreeSpecLike.scala:545)
	at org.scalatest.freespec.AsyncFreeSpec.run(AsyncFreeSpec.scala:2280)
	at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:321)
	at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:516)
	at sbt.ForkMain$Run.lambda$runTest$1(ForkMain.java:413)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)