summaryrefslogtreecommitdiff
path: root/src/main/java/org/mockito/internal/creation
diff options
context:
space:
mode:
authorGarfield Tan <xutan@google.com>2019-09-10 10:59:56 -0700
committerGarfield Tan <xutan@google.com>2019-09-10 15:27:13 -0700
commit49ce6eaa609cd48b55ae0387dbeb32ee8761bc63 (patch)
treebc8b6ddef81b0693a169e714db156fcb1378371b /src/main/java/org/mockito/internal/creation
parentc8600e6ec88a49c46f00d772e24c0139738a1020 (diff)
downloadmockito-49ce6eaa609cd48b55ae0387dbeb32ee8761bc63.tar.gz
Revert "Update to Mockito v2.25.7."
This reverts commit e14b62991dfb625a81997be77825455fdce66ebd. Bug: 140773999 Test: Builds. Change-Id: I299dabdf4fdb30845de3415ed8b2f727c5011098
Diffstat (limited to 'src/main/java/org/mockito/internal/creation')
-rw-r--r--src/main/java/org/mockito/internal/creation/MockSettingsImpl.java28
-rw-r--r--src/main/java/org/mockito/internal/creation/SuspendMethod.java10
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java27
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java53
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java3
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java32
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java251
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java166
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java37
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java11
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java35
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java11
-rw-r--r--src/main/java/org/mockito/internal/creation/settings/CreationSettings.java12
13 files changed, 130 insertions, 546 deletions
diff --git a/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java b/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java
index 50134b4..ca67730 100644
--- a/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java
+++ b/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java
@@ -11,7 +11,6 @@ import org.mockito.internal.util.Checks;
import org.mockito.internal.util.MockCreationValidator;
import org.mockito.internal.util.MockNameImpl;
import org.mockito.listeners.InvocationListener;
-import org.mockito.listeners.StubbingLookupListener;
import org.mockito.listeners.VerificationStartedListener;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.MockName;
@@ -20,17 +19,17 @@ import org.mockito.stubbing.Answer;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import static java.util.Arrays.asList;
import static org.mockito.internal.exceptions.Reporter.defaultAnswerDoesNotAcceptNullParameter;
import static org.mockito.internal.exceptions.Reporter.extraInterfacesAcceptsOnlyInterfaces;
import static org.mockito.internal.exceptions.Reporter.extraInterfacesDoesNotAcceptNullParameters;
import static org.mockito.internal.exceptions.Reporter.extraInterfacesRequiresAtLeastOneInterface;
+import static org.mockito.internal.exceptions.Reporter.invocationListenersRequiresAtLeastOneListener;
import static org.mockito.internal.exceptions.Reporter.methodDoesNotAcceptParameter;
-import static org.mockito.internal.exceptions.Reporter.requiresAtLeastOneListener;
import static org.mockito.internal.util.collections.Sets.newSet;
@SuppressWarnings("unchecked")
@@ -155,7 +154,7 @@ public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSett
}
List<Object> resultArgs = new ArrayList<Object>(constructorArgs.length + 1);
resultArgs.add(outerClassInstance);
- resultArgs.addAll(asList(constructorArgs));
+ resultArgs.addAll(Arrays.asList(constructorArgs));
return resultArgs.toArray(new Object[constructorArgs.length + 1]);
}
@@ -174,23 +173,17 @@ public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSett
@Override
public MockSettings invocationListeners(InvocationListener... listeners) {
+ if (listeners == null || listeners.length == 0) {
+ throw invocationListenersRequiresAtLeastOneListener();
+ }
addListeners(listeners, invocationListeners, "invocationListeners");
return this;
}
- @Override
- public MockSettings stubbingLookupListeners(StubbingLookupListener... listeners) {
- addListeners(listeners, stubbingLookupListeners, "stubbingLookupListeners");
- return this;
- }
-
- static <T> void addListeners(T[] listeners, List<T> container, String method) {
+ private static <T> void addListeners(T[] listeners, List<T> container, String method) {
if (listeners == null) {
throw methodDoesNotAcceptParameter(method, "null vararg array.");
}
- if (listeners.length == 0) {
- throw requiresAtLeastOneListener(method);
- }
for (T listener : listeners) {
if (listener == null) {
throw methodDoesNotAcceptParameter(method, "null listeners.");
@@ -214,8 +207,13 @@ public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSett
return false;
}
+ @Override
+ public List<InvocationListener> getInvocationListeners() {
+ return this.invocationListeners;
+ }
+
public boolean hasInvocationListeners() {
- return !getInvocationListeners().isEmpty();
+ return !invocationListeners.isEmpty();
}
@Override
diff --git a/src/main/java/org/mockito/internal/creation/SuspendMethod.java b/src/main/java/org/mockito/internal/creation/SuspendMethod.java
index 42ceac6..018bc50 100644
--- a/src/main/java/org/mockito/internal/creation/SuspendMethod.java
+++ b/src/main/java/org/mockito/internal/creation/SuspendMethod.java
@@ -11,18 +11,12 @@ import java.util.Arrays;
* See <a href="https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#continuation-passing-style">Design docs for details</a>.
*/
public class SuspendMethod {
- private static final String KOTLIN_EXPERIMENTAL_CONTINUATION = "kotlin.coroutines.experimental.Continuation";
- private static final String KOTLIN_CONTINUATION = "kotlin.coroutines.Continuation";
+ private static final String KOTLIN_CONTINUATION = "kotlin.coroutines.experimental.Continuation";
public static Class<?>[] trimSuspendParameterTypes(Class<?>[] parameterTypes) {
int n = parameterTypes.length;
- if (n > 0 && isContinuationType(parameterTypes[n - 1]))
+ if (n > 0 && parameterTypes[n - 1].getName().equals(KOTLIN_CONTINUATION))
return Arrays.copyOf(parameterTypes, n - 1);
return parameterTypes;
}
-
- private static boolean isContinuationType(Class<?> parameterType) {
- String name = parameterType.getName();
- return name.equals(KOTLIN_CONTINUATION) || name.equals(KOTLIN_EXPERIMENTAL_CONTINUATION);
- }
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java
index e99b915..42f10ce 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java
@@ -14,7 +14,6 @@ import org.mockito.internal.util.Platform;
import org.mockito.internal.util.concurrent.WeakConcurrentMap;
import org.mockito.invocation.MockHandler;
import org.mockito.mock.MockCreationSettings;
-import org.mockito.plugins.InlineMockMaker;
import java.io.File;
import java.io.FileOutputStream;
@@ -26,8 +25,6 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
-import javax.tools.ToolProvider;
-
import static org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.EXCLUDES;
import static org.mockito.internal.util.StringUtil.join;
@@ -90,7 +87,7 @@ import static org.mockito.internal.util.StringUtil.join;
* support this feature.
*/
@Incubating
-public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineMockMaker {
+public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker {
private static final Instrumentation INSTRUMENTATION;
@@ -112,7 +109,7 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM
boot.deleteOnExit();
JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(boot));
try {
- String source = "org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher";
+ String source = "org/mockito/internal/creation/bytebuddy/MockMethodDispatcher";
InputStream inputStream = InlineByteBuddyMockMaker.class.getClassLoader().getResourceAsStream(source + ".raw");
if (inputStream == null) {
throw new IllegalStateException(join(
@@ -137,7 +134,13 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM
}
instrumentation.appendToBootstrapClassLoaderSearch(new JarFile(boot));
try {
- Class.forName("org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher", false, null);
+ Class<?> dispatcher = Class.forName("org.mockito.internal.creation.bytebuddy.MockMethodDispatcher");
+ if (dispatcher.getClassLoader() != null) {
+ throw new IllegalStateException(join(
+ "The MockMethodDispatcher must not be loaded manually but must be injected into the bootstrap class loader.",
+ "",
+ "The dispatcher class was already loaded by: " + dispatcher.getClassLoader()));
+ }
} catch (ClassNotFoundException cnfe) {
throw new IllegalStateException(join(
"Mockito failed to inject the MockMethodDispatcher class into the bootstrap class loader",
@@ -167,7 +170,7 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM
if (INITIALIZATION_ERROR != null) {
throw new MockitoInitializationException(join(
"Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)",
- ToolProvider.getSystemJavaCompiler() == null ? "Are you running a JRE instead of a JDK? The inline mock maker needs to be run on a JDK.\n" : "",
+ "",
Platform.describe()), INITIALIZATION_ERROR);
}
bytecodeGenerator = new TypeCachingBytecodeGenerator(new InlineBytecodeGenerator(INSTRUMENTATION, mocks), true);
@@ -273,16 +276,6 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM
}
@Override
- public void clearMock(Object mock) {
- mocks.remove(mock);
- }
-
- @Override
- public void clearAllMocks() {
- mocks.clear();
- }
-
- @Override
public TypeMockability isTypeMockable(final Class<?> type) {
return new TypeMockability() {
@Override
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java
index e160e3c..64139c2 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java
@@ -26,17 +26,17 @@ import net.bytebuddy.pool.TypePool;
import net.bytebuddy.utility.OpenedClassReader;
import net.bytebuddy.utility.RandomString;
import org.mockito.exceptions.base.MockitoException;
-import org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher;
import org.mockito.internal.util.concurrent.WeakConcurrentMap;
import org.mockito.internal.util.concurrent.WeakConcurrentSet;
import org.mockito.mock.SerializableMode;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
-import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import static net.bytebuddy.implementation.MethodDelegation.withDefaultConfiguration;
import static net.bytebuddy.implementation.bind.annotation.TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of;
@@ -60,12 +60,14 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran
String.class));
private final Instrumentation instrumentation;
+
private final ByteBuddy byteBuddy;
+
private final WeakConcurrentSet<Class<?>> mocked;
+
private final BytecodeGenerator subclassEngine;
- private final AsmVisitorWrapper mockTransformer;
- private final Method getModule, canRead, redefineModule;
+ private final AsmVisitorWrapper mockTransformer;
private volatile Throwable lastException;
@@ -96,20 +98,6 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran
Advice.withCustomMapping()
.bind(MockMethodAdvice.Identifier.class, identifier)
.to(MockMethodAdvice.ForEquals.class));
- Method getModule, canRead, redefineModule;
- try {
- getModule = Class.class.getMethod("getModule");
- canRead = getModule.getReturnType().getMethod("canRead", getModule.getReturnType());
- redefineModule = Instrumentation.class.getMethod("redefineModule",
- getModule.getReturnType(), Set.class, Map.class, Map.class, Set.class, Map.class);
- } catch (Exception ignored) {
- getModule = null;
- canRead = null;
- redefineModule = null;
- }
- this.getModule = getModule;
- this.canRead = canRead;
- this.redefineModule = redefineModule;
MockMethodDispatcher.set(identifier, new MockMethodAdvice(mocks, identifier));
instrumentation.addTransformer(this, true);
}
@@ -170,7 +158,6 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran
} while (type != null);
if (!types.isEmpty()) {
try {
- assureCanReadMockito(types);
instrumentation.retransformClasses(types.toArray(new Class<?>[types.size()]));
Throwable throwable = lastException;
if (throwable != null) {
@@ -191,32 +178,6 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran
}
}
- private void assureCanReadMockito(Set<Class<?>> types) {
- if (redefineModule == null) {
- return;
- }
- Set<Object> modules = new HashSet<Object>();
- try {
- Object target = getModule.invoke(Class.forName("org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher", false, null));
- for (Class<?> type : types) {
- Object module = getModule.invoke(type);
- if (!modules.contains(module) && !(Boolean) canRead.invoke(module, target)) {
- modules.add(module);
- }
- }
- for (Object module : modules) {
- redefineModule.invoke(instrumentation, module, Collections.singleton(target),
- Collections.emptyMap(), Collections.emptyMap(), Collections.emptySet(), Collections.emptyMap());
- }
- } catch (Exception e) {
- throw new IllegalStateException(join("Could not adjust module graph to make the mock instance dispatcher visible to some classes",
- "",
- "At least one of those modules: " + modules + " is not reading the unnamed module of the bootstrap loader",
- "Without such a read edge, the classes that are redefined to become mocks cannot access the mock dispatcher.",
- "To circumvent this, Mockito attempted to add a read edge to this module what failed for an unexpected reason"), e);
- }
- }
-
private <T> void checkSupportedCombination(boolean subclassingRequired, MockFeatures<T> features) {
if (subclassingRequired
&& !features.mockedType.isArray()
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java
index 828b848..f39a1a2 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java
@@ -12,7 +12,6 @@ import net.bytebuddy.implementation.bind.annotation.Argument;
import net.bytebuddy.implementation.bind.annotation.This;
import net.bytebuddy.implementation.bytecode.assign.Assigner;
import org.mockito.exceptions.base.MockitoException;
-import org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher;
import org.mockito.internal.debugging.LocationImpl;
import org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter;
import org.mockito.internal.invocation.RealMethod;
@@ -36,7 +35,7 @@ import java.util.concurrent.Callable;
public class MockMethodAdvice extends MockMethodDispatcher {
- private final WeakConcurrentMap<Object, MockMethodInterceptor> interceptors;
+ final WeakConcurrentMap<Object, MockMethodInterceptor> interceptors;
private final String identifier;
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java
index e57a82e..9066927 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java
@@ -46,11 +46,13 @@ public class MockMethodInterceptor implements Serializable {
Method invokedMethod,
Object[] arguments,
RealMethod realMethod) throws Throwable {
- return doIntercept(mock,
- invokedMethod,
- arguments,
- realMethod,
- new LocationImpl());
+ return doIntercept(
+ mock,
+ invokedMethod,
+ arguments,
+ realMethod,
+ new LocationImpl()
+ );
}
Object doIntercept(Object mock,
@@ -106,11 +108,11 @@ public class MockMethodInterceptor implements Serializable {
return superCall.call();
}
return interceptor.doIntercept(
- mock,
- invokedMethod,
- arguments,
- new RealMethod.FromCallable(superCall)
- );
+ mock,
+ invokedMethod,
+ arguments,
+ new RealMethod.FromCallable(superCall)
+ );
}
@SuppressWarnings("unused")
@@ -124,11 +126,11 @@ public class MockMethodInterceptor implements Serializable {
return stubValue;
}
return interceptor.doIntercept(
- mock,
- invokedMethod,
- arguments,
- RealMethod.IsIllegal.INSTANCE
- );
+ mock,
+ invokedMethod,
+ arguments,
+ RealMethod.IsIllegal.INSTANCE
+ );
}
}
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java b/src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java
deleted file mode 100644
index 5be0b95..0000000
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2016 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.creation.bytebuddy;
-
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.modifier.Ownership;
-import net.bytebuddy.description.modifier.Visibility;
-import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
-import net.bytebuddy.implementation.Implementation;
-import net.bytebuddy.implementation.MethodCall;
-import net.bytebuddy.implementation.StubMethod;
-import org.mockito.codegen.InjectionBase;
-import org.mockito.exceptions.base.MockitoException;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Random;
-
-import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer;
-import static org.mockito.internal.util.StringUtil.join;
-
-abstract class ModuleHandler {
-
- abstract boolean isOpened(Class<?> source, Class<?> target);
-
- abstract boolean canRead(Class<?> source, Class<?> target);
-
- abstract boolean isExported(Class<?> source);
-
- abstract boolean isExported(Class<?> source, Class<?> target);
-
- abstract Class<?> injectionBase(ClassLoader classLoader, String tyoeName);
-
- abstract void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read);
-
- static ModuleHandler make(ByteBuddy byteBuddy, SubclassLoader loader, Random random) {
- try {
- return new ModuleSystemFound(
- byteBuddy, loader, random
- );
- } catch (Exception ignored) {
- return new NoModuleSystemFound();
- }
- }
-
- private static class ModuleSystemFound extends ModuleHandler {
-
- private final ByteBuddy byteBuddy;
- private final SubclassLoader loader;
- private final Random random;
-
- private final int injectonBaseSuffix;
-
- private final Method getModule, isOpen, isExported, isExportedUnqualified, canRead, addExports, addReads, addOpens, forName;
-
- private ModuleSystemFound(ByteBuddy byteBuddy, SubclassLoader loader, Random random) throws Exception {
- this.byteBuddy = byteBuddy;
- this.loader = loader;
- this.random = random;
- injectonBaseSuffix = Math.abs(random.nextInt());
- Class<?> moduleType = Class.forName("java.lang.Module");
- getModule = Class.class.getMethod("getModule");
- isOpen = moduleType.getMethod("isOpen", String.class, moduleType);
- isExported = moduleType.getMethod("isExported", String.class, moduleType);
- isExportedUnqualified = moduleType.getMethod("isExported", String.class);
- canRead = moduleType.getMethod("canRead", moduleType);
- addExports = moduleType.getMethod("addExports", String.class, moduleType);
- addReads = moduleType.getMethod("addReads", moduleType);
- addOpens = moduleType.getMethod("addOpens", String.class, moduleType);
- forName = Class.class.getMethod("forName", String.class);
- }
-
- @Override
- boolean isOpened(Class<?> source, Class<?> target) {
- if (source.getPackage() == null) {
- return true;
- }
- return (Boolean) invoke(isOpen, invoke(getModule, source), source.getPackage().getName(), invoke(getModule, target));
- }
-
- @Override
- boolean canRead(Class<?> source, Class<?> target) {
- return (Boolean) invoke(canRead, invoke(getModule, source), invoke(getModule, target));
- }
-
- @Override
- boolean isExported(Class<?> source) {
- if (source.getPackage() == null) {
- return true;
- }
- return (Boolean) invoke(isExportedUnqualified, invoke(getModule, source), source.getPackage().getName());
- }
-
- @Override
- boolean isExported(Class<?> source, Class<?> target) {
- if (source.getPackage() == null) {
- return true;
- }
- return (Boolean) invoke(isExported, invoke(getModule, source), source.getPackage().getName(), invoke(getModule, target));
- }
-
- @Override
- Class<?> injectionBase(ClassLoader classLoader, String typeName) {
- String packageName = typeName.substring(0, typeName.lastIndexOf('.'));
- if (classLoader == InjectionBase.class.getClassLoader() && InjectionBase.class.getPackage().getName().equals(packageName)) {
- return InjectionBase.class;
- } else {
- synchronized (this) {
- String name;
- int suffix = injectonBaseSuffix;
- do {
- name = packageName + "." + InjectionBase.class.getSimpleName() + "$" + suffix++;
- try {
- Class<?> type = Class.forName(name, false, classLoader);
- // The injected type must be defined in the class loader that is target of the injection. Otherwise,
- // the class's unnamed module would differ from the intended module. To avoid conflicts, we increment
- // the suffix until we hit a class with a known name and generate one if it does not exist.
- if (type.getClassLoader() == classLoader) {
- return type;
- }
- } catch (ClassNotFoundException ignored) {
- break;
- }
- } while (true);
- return byteBuddy.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
- .name(name)
- .make()
- .load(classLoader, loader.resolveStrategy(InjectionBase.class, classLoader, false))
- .getLoaded();
- }
- }
- }
-
- @Override
- void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read) {
- boolean needsExport = export && !isExported(source, target);
- boolean needsRead = read && !canRead(source, target);
- if (!needsExport && !needsRead) {
- return;
- }
- ClassLoader classLoader = source.getClassLoader();
- if (classLoader == null) {
- throw new MockitoException(join("Cannot adjust module graph for modules in the bootstrap loader",
- "",
- source + " is declared by the bootstrap loader and cannot be adjusted",
- "Requires package export to " + target + ": " + needsExport,
- "Requires adjusted reading of " + target + ": " + needsRead));
- }
- boolean targetVisible = classLoader == target.getClassLoader();
- while (!targetVisible && classLoader != null) {
- classLoader = classLoader.getParent();
- targetVisible = classLoader == target.getClassLoader();
- }
- MethodCall targetLookup;
- Implementation.Composable implementation;
- if (targetVisible) {
- targetLookup = MethodCall.invoke(getModule).onMethodCall(MethodCall.invoke(forName).with(target.getName()));
- implementation = StubMethod.INSTANCE;
- } else {
- Class<?> intermediate;
- Field field;
- try {
- intermediate = byteBuddy.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
- .name(String.format("%s$%d", "org.mockito.codegen.MockitoTypeCarrier", Math.abs(random.nextInt())))
- .defineField("mockitoType", Class.class, Visibility.PUBLIC, Ownership.STATIC)
- .make()
- .load(source.getClassLoader(), loader.resolveStrategy(source, source.getClassLoader(), false))
- .getLoaded();
- field = intermediate.getField("mockitoType");
- field.set(null, target);
- } catch (Exception e) {
- throw new MockitoException(join("Could not create a carrier for making the Mockito type visible to " + source,
- "",
- "This is required to adjust the module graph to enable mock creation"), e);
- }
- targetLookup = MethodCall.invoke(getModule).onField(field);
- implementation = MethodCall.invoke(getModule).onMethodCall(MethodCall.invoke(forName).with(intermediate.getName()));
- }
- MethodCall sourceLookup = MethodCall.invoke(getModule).onMethodCall(MethodCall.invoke(forName).with(source.getName()));
- if (needsExport) {
- implementation = implementation.andThen(MethodCall.invoke(addExports)
- .onMethodCall(sourceLookup)
- .with(target.getPackage().getName())
- .withMethodCall(targetLookup));
- }
- if (needsRead) {
- implementation = implementation.andThen(MethodCall.invoke(addReads)
- .onMethodCall(sourceLookup)
- .withMethodCall(targetLookup));
- }
- try {
- Class.forName(byteBuddy.subclass(Object.class)
- .name(String.format("%s$%s$%d", source.getName(), "MockitoModuleProbe", Math.abs(random.nextInt())))
- .invokable(isTypeInitializer()).intercept(implementation)
- .make()
- .load(source.getClassLoader(), loader.resolveStrategy(source, source.getClassLoader(), false))
- .getLoaded()
- .getName(), true, source.getClassLoader());
- } catch (Exception e) {
- throw new MockitoException(join("Could not force module adjustment of the module of " + source,
- "",
- "This is required to adjust the module graph to enable mock creation"), e);
- }
- }
-
- private static Object invoke(Method method, Object target, Object... args) {
- try {
- return method.invoke(target, args);
- } catch (Exception e) {
- throw new MockitoException(join("Could not invoke " + method + " using reflection",
- "",
- "Mockito attempted to interact with the Java module system but an unexpected method behavior was encountered"), e);
- }
- }
- }
-
- private static class NoModuleSystemFound extends ModuleHandler {
-
- @Override
- boolean isOpened(Class<?> source, Class<?> target) {
- return true;
- }
-
- @Override
- boolean canRead(Class<?> source, Class<?> target) {
- return true;
- }
-
- @Override
- boolean isExported(Class<?> source) {
- return true;
- }
-
- @Override
- boolean isExported(Class<?> source, Class<?> target) {
- return true;
- }
-
- @Override
- Class<?> injectionBase(ClassLoader classLoader, String tyoeName) {
- return InjectionBase.class;
- }
-
- @Override
- void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read) {
- // empty
- }
- }
-}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java
index 093978d..b659c73 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java
@@ -15,7 +15,6 @@ import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.attribute.MethodAttributeAppender;
import net.bytebuddy.matcher.ElementMatcher;
-import org.mockito.codegen.InjectionBase;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.creation.bytebuddy.ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializableMock;
import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.DispatcherDefaultingToRealMethod;
@@ -27,9 +26,6 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
import java.util.Random;
import static java.lang.Thread.currentThread;
@@ -45,9 +41,10 @@ class SubclassBytecodeGenerator implements BytecodeGenerator {
private static final String CODEGEN_PACKAGE = "org.mockito.codegen.";
private final SubclassLoader loader;
- private final ModuleHandler handler;
+
private final ByteBuddy byteBuddy;
private final Random random;
+
private final Implementation readReplace;
private final ElementMatcher<? super MethodDescription> matcher;
@@ -74,128 +71,95 @@ class SubclassBytecodeGenerator implements BytecodeGenerator {
this.matcher = matcher;
byteBuddy = new ByteBuddy().with(TypeValidation.DISABLED);
random = new Random();
- handler = ModuleHandler.make(byteBuddy, loader, random);
}
@Override
public <T> Class<? extends T> mockClass(MockFeatures<T> features) {
- ClassLoader classLoader = new MultipleParentClassLoader.Builder()
- .appendMostSpecific(getAllTypes(features.mockedType))
- .appendMostSpecific(features.interfaces)
- .appendMostSpecific(currentThread().getContextClassLoader())
- .appendMostSpecific(MockAccess.class)
- .build();
-
- // If Mockito does not need to create a new class loader and if a mock is not based on a JDK type, we attempt
- // to define the mock class in the user runtime package to allow for mocking package private types and methods.
- // This also requires that we are able to access the package of the mocked class either by override or explicit
- // privilege given by the target package being opened to Mockito.
- boolean localMock = classLoader == features.mockedType.getClassLoader()
- && features.serializableMode != SerializableMode.ACROSS_CLASSLOADERS
- && !isComingFromJDK(features.mockedType)
- && (loader.isDisrespectingOpenness() || handler.isOpened(features.mockedType, MockAccess.class));
- String typeName;
- if (localMock || loader instanceof MultipleParentClassLoader && !isComingFromJDK(features.mockedType)) {
- typeName = features.mockedType.getName();
- } else {
- typeName = InjectionBase.class.getPackage().getName() + "." + features.mockedType.getSimpleName();
- }
- String name = String.format("%s$%s$%d", typeName, "MockitoMock", Math.abs(random.nextInt()));
-
- if (localMock) {
- handler.adjustModuleGraph(features.mockedType, MockAccess.class, false, true);
- for (Class<?> iFace : features.interfaces) {
- handler.adjustModuleGraph(iFace, features.mockedType, true, false);
- handler.adjustModuleGraph(features.mockedType, iFace, false, true);
- }
- } else {
- boolean exported = handler.isExported(features.mockedType);
- Iterator<Class<?>> it = features.interfaces.iterator();
- while (exported && it.hasNext()) {
- exported = handler.isExported(it.next());
- }
- // We check if all mocked types are exported without qualification to avoid generating a hook type.
- // unless this is necessary. We expect this to be the case for most mocked types what makes this a
- // worthy performance optimization.
- if (exported) {
- assertVisibility(features.mockedType);
- for (Class<?> iFace : features.interfaces) {
- assertVisibility(iFace);
- }
- } else {
- Class<?> hook = handler.injectionBase(classLoader, typeName);
- assertVisibility(features.mockedType);
- handler.adjustModuleGraph(features.mockedType, hook, true, false);
- for (Class<?> iFace : features.interfaces) {
- assertVisibility(iFace);
- handler.adjustModuleGraph(iFace, hook, true, false);
- }
- }
- }
-
- DynamicType.Builder<T> builder = byteBuddy.subclass(features.mockedType)
- .name(name)
- .ignoreAlso(isGroovyMethod())
- .annotateType(features.stripAnnotations
- ? new Annotation[0]
- : features.mockedType.getAnnotations())
- .implement(new ArrayList<Type>(features.interfaces))
- .method(matcher)
- .intercept(dispatcher)
- .transform(withModifiers(SynchronizationState.PLAIN))
- .attribute(features.stripAnnotations
- ? MethodAttributeAppender.NoOp.INSTANCE
- : INCLUDING_RECEIVER)
- .method(isHashCode())
- .intercept(hashCode)
- .method(isEquals())
- .intercept(equals)
- .serialVersionUid(42L)
- .defineField("mockitoInterceptor", MockMethodInterceptor.class, PRIVATE)
- .implement(MockAccess.class)
- .intercept(FieldAccessor.ofBeanProperty());
+ String name = nameFor(features.mockedType);
+ DynamicType.Builder<T> builder =
+ byteBuddy.subclass(features.mockedType)
+ .name(name)
+ .ignoreAlso(isGroovyMethod())
+ .annotateType(features.stripAnnotations
+ ? new Annotation[0]
+ : features.mockedType.getAnnotations())
+ .implement(new ArrayList<Type>(features.interfaces))
+ .method(matcher)
+ .intercept(dispatcher)
+ .transform(withModifiers(SynchronizationState.PLAIN))
+ .attribute(features.stripAnnotations
+ ? MethodAttributeAppender.NoOp.INSTANCE
+ : INCLUDING_RECEIVER)
+ .method(isHashCode())
+ .intercept(hashCode)
+ .method(isEquals())
+ .intercept(equals)
+ .serialVersionUid(42L)
+ .defineField("mockitoInterceptor", MockMethodInterceptor.class, PRIVATE)
+ .implement(MockAccess.class)
+ .intercept(FieldAccessor.ofBeanProperty());
if (features.serializableMode == SerializableMode.ACROSS_CLASSLOADERS) {
builder = builder.implement(CrossClassLoaderSerializableMock.class)
- .intercept(writeReplace);
+ .intercept(writeReplace);
}
if (readReplace != null) {
builder = builder.defineMethod("readObject", void.class, Visibility.PRIVATE)
- .withParameters(ObjectInputStream.class)
- .throwing(ClassNotFoundException.class, IOException.class)
- .intercept(readReplace);
+ .withParameters(ObjectInputStream.class)
+ .throwing(ClassNotFoundException.class, IOException.class)
+ .intercept(readReplace);
}
- if (name.startsWith(CODEGEN_PACKAGE) || classLoader instanceof MultipleParentClassLoader) {
+ ClassLoader classLoader = new MultipleParentClassLoader.Builder()
+ .append(features.mockedType)
+ .append(features.interfaces)
+ .append(currentThread().getContextClassLoader())
+ .append(MockAccess.class, DispatcherDefaultingToRealMethod.class)
+ .append(MockMethodInterceptor.class,
+ MockMethodInterceptor.ForHashCode.class,
+ MockMethodInterceptor.ForEquals.class).build(MockMethodInterceptor.class.getClassLoader());
+ if (classLoader != features.mockedType.getClassLoader()) {
+ assertVisibility(features.mockedType);
+ for (Class<?> iFace : features.interfaces) {
+ assertVisibility(iFace);
+ }
builder = builder.ignoreAlso(isPackagePrivate()
.or(returns(isPackagePrivate()))
.or(hasParameters(whereAny(hasType(isPackagePrivate())))));
}
return builder.make()
- .load(classLoader, loader.resolveStrategy(features.mockedType, classLoader, localMock))
- .getLoaded();
- }
-
- private <T> Collection<Class<? super T>> getAllTypes(Class<T> type) {
- Collection<Class<? super T>> supertypes = new LinkedList<Class<? super T>>();
- supertypes.add(type);
- Class<? super T> superType = type;
- while (superType != null) {
- supertypes.add(superType);
- superType = superType.getSuperclass();
- }
- return supertypes;
+ .load(classLoader, loader.resolveStrategy(features.mockedType, classLoader, name.startsWith(CODEGEN_PACKAGE)))
+ .getLoaded();
}
private static ElementMatcher<MethodDescription> isGroovyMethod() {
return isDeclaredBy(named("groovy.lang.GroovyObjectSupport"));
}
+ // TODO inspect naming strategy (for OSGI, signed package, java.* (and bootstrap classes), etc...)
+ private String nameFor(Class<?> type) {
+ String typeName = type.getName();
+ if (isComingFromJDK(type)
+ || isComingFromSignedJar(type)
+ || isComingFromSealedPackage(type)) {
+ typeName = CODEGEN_PACKAGE + type.getSimpleName();
+ }
+ return String.format("%s$%s$%d", typeName, "MockitoMock", Math.abs(random.nextInt()));
+ }
+
private boolean isComingFromJDK(Class<?> type) {
// Comes from the manifest entry :
// Implementation-Title: Java Runtime Environment
// This entry is not necessarily present in every jar of the JDK
return type.getPackage() != null && "Java Runtime Environment".equalsIgnoreCase(type.getPackage().getImplementationTitle())
- || type.getName().startsWith("java.")
- || type.getName().startsWith("javax.");
+ || type.getName().startsWith("java.")
+ || type.getName().startsWith("javax.");
+ }
+
+ private boolean isComingFromSealedPackage(Class<?> type) {
+ return type.getPackage() != null && type.getPackage().isSealed();
+ }
+
+ private boolean isComingFromSignedJar(Class<?> type) {
+ return type.getSigners() != null;
}
private static void assertVisibility(Class<?> type) {
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java
index 89b0a30..454dd8e 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java
@@ -25,7 +25,7 @@ class SubclassInjectionLoader implements SubclassLoader {
private final SubclassLoader loader;
SubclassInjectionLoader() {
- if (!Boolean.getBoolean("org.mockito.internal.noUnsafeInjection") && ClassInjector.UsingReflection.isAvailable()) {
+ if (!Boolean.getBoolean("org.mockito.internal.simulateJava11") && ClassInjector.UsingReflection.isAvailable()) {
this.loader = new WithReflection();
} else if (ClassInjector.UsingLookup.isAvailable()) {
this.loader = tryLookup();
@@ -49,13 +49,8 @@ class SubclassInjectionLoader implements SubclassLoader {
private static class WithReflection implements SubclassLoader {
@Override
- public boolean isDisrespectingOpenness() {
- return true;
- }
-
- @Override
- public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock) {
- return ClassLoadingStrategy.Default.INJECTION.with(localMock ? mockedType.getProtectionDomain() : InjectionBase.class.getProtectionDomain());
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
+ return ClassLoadingStrategy.Default.INJECTION.with(codegen ? InjectionBase.class.getProtectionDomain() : mockedType.getProtectionDomain());
}
}
@@ -74,13 +69,12 @@ class SubclassInjectionLoader implements SubclassLoader {
}
@Override
- public boolean isDisrespectingOpenness() {
- return false;
- }
-
- @Override
- public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock) {
- if (localMock) {
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
+ if (codegen) {
+ return ClassLoadingStrategy.UsingLookup.of(codegenLookup);
+ } else if (classLoader != mockedType.getClassLoader()) {
+ return ClassLoadingStrategy.Default.WRAPPER.with(mockedType.getProtectionDomain());
+ } else {
try {
Object privateLookup;
try {
@@ -102,21 +96,12 @@ class SubclassInjectionLoader implements SubclassLoader {
exception
));
}
- } else if (classLoader == InjectionBase.class.getClassLoader()) {
- return ClassLoadingStrategy.UsingLookup.of(codegenLookup);
- } else {
- return ClassLoadingStrategy.Default.WRAPPER.with(mockedType.getProtectionDomain());
}
}
}
@Override
- public boolean isDisrespectingOpenness() {
- return loader.isDisrespectingOpenness();
- }
-
- @Override
- public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock) {
- return loader.resolveStrategy(mockedType, classLoader, localMock);
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
+ return loader.resolveStrategy(mockedType, classLoader, codegen);
}
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java
index 011504e..194c282 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java
@@ -12,19 +12,12 @@ import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
public interface SubclassLoader {
/**
- * Checks if this loader does not require a module to be open.
- *
- * @return {@code true} if this loader is not constraint to a target module being opened for loading a class.
- */
- boolean isDisrespectingOpenness();
-
- /**
* Resolves a class loading strategy.
*
* @param mockedType The type being mocked.
* @param classLoader The class loader being used.
- * @param localMock {@code true} if the mock is loaded within the runtime package of the mocked type.
+ * @param codegen {@code true} if the mock is loaded in the {@code org.mockito.codegen} package.
* @return An appropriate class loading strategy.
*/
- ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock);
+ ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen);
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java b/src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java
deleted file mode 100644
index 12e30db..0000000
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2016 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.creation.bytebuddy.inject;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-public abstract class MockMethodDispatcher {
-
- private static final ConcurrentMap<String, MockMethodDispatcher> INSTANCE = new ConcurrentHashMap<String, MockMethodDispatcher>();
-
- public static MockMethodDispatcher get(String identifier, Object mock) {
- if (mock == INSTANCE) { // Avoid endless loop if ConcurrentHashMap was redefined to check for being a mock.
- return null;
- } else {
- return INSTANCE.get(identifier);
- }
- }
-
- public static void set(String identifier, MockMethodDispatcher dispatcher) {
- INSTANCE.putIfAbsent(identifier, dispatcher);
- }
-
- public abstract Callable<?> handle(Object instance, Method origin, Object[] arguments) throws Throwable;
-
- public abstract boolean isMock(Object instance);
-
- public abstract boolean isMocked(Object instance);
-
- public abstract boolean isOverridden(Object instance, Method origin);
-}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java b/src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java
deleted file mode 100644
index 5abed05..0000000
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-
-/**
- * Internal classes, not to be used by clients. Intended for injection into the bootstrap class loader.
- *
- * Subject to change at any time without notice.
- */
-package org.mockito.internal.creation.bytebuddy.inject;
diff --git a/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java b/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java
index 3b45592..03afd80 100644
--- a/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java
+++ b/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java
@@ -4,8 +4,8 @@
*/
package org.mockito.internal.creation.settings;
+import org.mockito.internal.listeners.StubbingLookupListener;
import org.mockito.listeners.InvocationListener;
-import org.mockito.listeners.StubbingLookupListener;
import org.mockito.listeners.VerificationStartedListener;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.MockName;
@@ -18,7 +18,6 @@ import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
public class CreationSettings<T> implements MockCreationSettings<T>, Serializable {
private static final long serialVersionUID = -6789800638070123629L;
@@ -31,11 +30,7 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl
protected MockName mockName;
protected SerializableMode serializableMode = SerializableMode.NONE;
protected List<InvocationListener> invocationListeners = new ArrayList<InvocationListener>();
-
- //Other listeners in this class may also need concurrency-safe implementation. However, no issue was reported about it.
- // If we do it, we need to understand usage patterns and choose the right concurrent implementation.
- protected List<StubbingLookupListener> stubbingLookupListeners = new CopyOnWriteArrayList<StubbingLookupListener>();
-
+ protected final List<StubbingLookupListener> stubbingLookupListeners = new ArrayList<StubbingLookupListener>();
protected List<VerificationStartedListener> verificationStartedListeners = new LinkedList<VerificationStartedListener>();
protected boolean stubOnly;
protected boolean stripAnnotations;
@@ -48,7 +43,6 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl
@SuppressWarnings("unchecked")
public CreationSettings(CreationSettings copy) {
- //TODO can we have a reflection test here? We had a couple of bugs here in the past.
this.typeToMock = copy.typeToMock;
this.extraInterfaces = copy.extraInterfaces;
this.name = copy.name;
@@ -57,14 +51,12 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl
this.mockName = copy.mockName;
this.serializableMode = copy.serializableMode;
this.invocationListeners = copy.invocationListeners;
- this.stubbingLookupListeners = copy.stubbingLookupListeners;
this.verificationStartedListeners = copy.verificationStartedListeners;
this.stubOnly = copy.stubOnly;
this.useConstructor = copy.isUsingConstructor();
this.outerClassInstance = copy.getOuterClassInstance();
this.constructorArgs = copy.getConstructorArgs();
this.lenient = copy.lenient;
- this.stripAnnotations = copy.stripAnnotations;
}
@Override