From 61edc0abdf5316806573f7c51f0ca00b05ceeecf Mon Sep 17 00:00:00 2001 From: trompa Date: Tue, 2 Feb 2021 21:09:32 +0100 Subject: [PATCH] #350 Fix Refelction utils for java 13+ (#356) * 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 [skip ci] --- .../main/scala/org/mockito/MockitoAPI.scala | 22 +----------------- .../scala/org/mockito/ReflectionUtils.scala | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/common/src/main/scala/org/mockito/MockitoAPI.scala b/common/src/main/scala/org/mockito/MockitoAPI.scala index be0d50ae..85f97963 100644 --- a/common/src/main/scala/org/mockito/MockitoAPI.scala +++ b/common/src/main/scala/org/mockito/MockitoAPI.scala @@ -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 @@ -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( diff --git a/common/src/main/scala/org/mockito/ReflectionUtils.scala b/common/src/main/scala/org/mockito/ReflectionUtils.scala index cd41851e..64057f9b 100644 --- a/common/src/main/scala/org/mockito/ReflectionUtils.scala +++ b/common/src/main/scala/org/mockito/ReflectionUtils.scala @@ -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 { @@ -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) } + }