Skip to content

Commit

Permalink
#350 Fix Refelction utils for java 13+ (#356)
Browse files Browse the repository at this point in the history
* getField for java 12+

* Fix for java 13+, avoid type conversion error

* Fix the right method

* undo allchanges

* undo allchanges

* remove unused import

* sync upstream and apply changes

Co-authored-by: Alberto Lago <[email protected]>

[skip ci]
  • Loading branch information
trompa authored Feb 2, 2021
1 parent fd57003 commit 61edc0a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 22 deletions.
22 changes: 1 addition & 21 deletions common/src/main/scala/org/mockito/MockitoAPI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,9 @@ import org.mockito.stubbing._
import org.mockito.verification.{ VerificationAfterDelay, VerificationMode, VerificationWithTimeout }
import org.scalactic.{ Equality, Prettifier }

import java.lang.reflect.Field
import scala.collection.JavaConverters._
import scala.reflect.ClassTag
import scala.reflect.runtime.universe.WeakTypeTag
import scala.util.{ Failure, Success, Try }
import scala.util.control.Breaks.break

private[mockito] trait ScalacticSerialisableHack {
//Hack until Equality can be made serialisable
Expand Down Expand Up @@ -633,24 +630,7 @@ private[mockito] trait MockitoEnhancer extends MockCreator {
def withObjectMocked[O <: AnyRef: ClassTag](block: => Any)(implicit defaultAnswer: DefaultAnswer, $pt: Prettifier): Unit = {
val objectClass = clazz[O]
objectClass.synchronized {
val moduleField: Field = Try(objectClass.getDeclaredField("MODULE$")) match {
case Success(module) => module
case Failure(e) =>
Try {
val getDeclaredFields0 = objectClass.getDeclaredMethod("getDeclaredFields0", classOf[Boolean])
val accessibleBeforeSet: Boolean = getDeclaredFields0.isAccessible
getDeclaredFields0.setAccessible(true)
val declaredFields: Array[Field] = getDeclaredFields0.invoke(classOf[Field], () => false).asInstanceOf[Array[Field]]
getDeclaredFields0.setAccessible(accessibleBeforeSet)
declaredFields.find("MODULE$" == _.getName).get
} match {
case Success(module) => module
case Failure(ex) =>
e.addSuppressed(ex)
throw e
}
}

val moduleField = objectClass.getDeclaredField("MODULE$")
val realImpl: O = moduleField.get(null).asInstanceOf[O]

val threadAwareMock = createMock(
Expand Down
23 changes: 22 additions & 1 deletion common/src/main/scala/org/mockito/ReflectionUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ru.vyarus.java.generics.resolver.GenericsResolver

import scala.reflect.ClassTag
import scala.reflect.internal.Symbols
import scala.util.{ Failure, Success, Try => uTry }
import scala.util.control.NonFatal

object ReflectionUtils {
Expand Down Expand Up @@ -124,10 +125,30 @@ object ReflectionUtils {
}

def setFinalStatic(field: Field, newValue: Any): Unit = {
val clazz = classOf[java.lang.Class[_]]
field.setAccessible(true)
val modifiersField = classOf[Field].getDeclaredField("modifiers")
val modifiersField: Field = uTry(clazz.getDeclaredField("modifiers")) match {
case Success(modifiers) => modifiers
case Failure(e) =>
uTry {
val getDeclaredFields0 = clazz.getDeclaredMethod("getDeclaredFields0", classOf[Boolean])
val accessibleBeforeSet: Boolean = getDeclaredFields0.isAccessible
getDeclaredFields0.setAccessible(true)
val declaredFields: Array[Field] = getDeclaredFields0
.invoke(classOf[Field], java.lang.Boolean.FALSE)
.asInstanceOf[Array[Field]]
getDeclaredFields0.setAccessible(accessibleBeforeSet)
declaredFields.find("modifiers" == _.getName).get
} match {
case Success(modifiers) => modifiers
case Failure(ex) =>
e.addSuppressed(ex)
throw e
}
}
modifiersField.setAccessible(true)
modifiersField.setInt(field, field.getModifiers & ~Modifier.FINAL)
field.set(null, newValue)
}

}

0 comments on commit 61edc0a

Please sign in to comment.