Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
kwhitehouse opened this issue Aug 31, 2022 · 0 comments

Comments

@kwhitehouse
Copy link

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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant