Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.agent.ByteBuddyAgent;
import org.mockito.MockedConstruction;
import org.mockito.creation.instance.InstantiationException;
import org.mockito.creation.instance.Instantiator;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.exceptions.base.MockitoInitializationException;
import org.mockito.exceptions.misusing.MockitoConfigurationException;
import org.mockito.internal.SuppressSignatureCheck;
import org.mockito.internal.configuration.plugins.Plugins;
import org.mockito.internal.creation.instance.ConstructorInstantiator;
import org.mockito.internal.util.Platform;
import org.mockito.internal.util.concurrent.DetachedThreadLocal;
import org.mockito.internal.util.concurrent.WeakConcurrentMap;
import org.mockito.invocation.MockHandler;
import org.mockito.mock.MockCreationSettings;
import org.mockito.plugins.InlineMockMaker;
import org.mockito.plugins.MemberAccessor;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import static org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.EXCLUDES;
import static org.mockito.internal.util.StringUtil.join;
/**
* Agent and subclass based mock maker.
*
* This mock maker uses a combination of the Java instrumentation API and sub-classing rather than creating
* a new sub-class to create a mock. This way, it becomes possible to mock final types and methods. This mock
* maker must be activated explicitly for supporting mocking final types and methods:
*
*
* This mock maker can be activated by creating the file /mockito-extensions/org.mockito.plugins.MockMaker
* containing the text mock-maker-inline or org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.
*
*
* This mock maker will make a best effort to avoid subclass creation when creating a mock. Otherwise it will use the
* org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker to create the mock class. That means
* that the following condition is true
*
* Some type of the JDK cannot be mocked, this includes Class, String, and wrapper types.
*
*
* Nevertheless, final methods of such types are mocked when using the inlining mock maker. Mocking final types and enums
* does however remain impossible when explicitly requiring serialization support or when adding ancillary interfaces.
*
*
* Important behavioral changes when using inline-mocks:
*
*
Mockito is capable of mocking package-private methods even if they are defined in different packages than
* the mocked type. Mockito voluntarily never mocks package-visible methods within java.* packages.
*
Additionally to final types, Mockito can now mock types that are not visible for extension; such types
* include private types in a protected package.
*
Mockito can no longer mock native methods. Inline mocks require byte code manipulation of a
* method where native methods do not offer any byte code to manipulate.
*
Mockito can no longer strip synchronized modifiers from mocked instances.
*
*
*
* Note that inline mocks require a Java agent to be attached. Mockito will attempt an attachment of a Java agent upon
* loading the mock maker for creating inline mocks. Such runtime attachment is only possible when using a JVM that
* is part of a JDK or when using a Java 9 VM. When running on a non-JDK VM prior to Java 9, it is however possible to
* manually add the Byte Buddy Java agent jar using the -javaagent
* parameter upon starting the JVM. Furthermore, the inlining mock maker requires the VM to support class retransformation
* (also known as HotSwap). All major VM distributions such as HotSpot (OpenJDK), J9 (IBM/Websphere) or Zing (Azul)
* support this feature.
*/
@SuppressSignatureCheck
class InlineDelegateByteBuddyMockMaker
implements ClassCreatingMockMaker, InlineMockMaker, Instantiator {
private static final Instrumentation INSTRUMENTATION;
private static final Throwable INITIALIZATION_ERROR;
static {
Instrumentation instrumentation;
Throwable initializationError = null;
// ByteBuddy internally may attempt to fork a subprocess. In Java 11 and Java 19, the Java
// process class observes the os.name system property to determine the OS and thus determine
// how to fork a new process. If the user is stubbing System properties, they may clear
// the existing System properties, which will cause this to fail. This is very much an
// implementation detail, but it will result in Mockito failing to load with an error that
// is not overly clear, so let's attempt to detect this issue ahead of time instead.
if (System.getProperty("os.name") == null) {
throw new IllegalStateException(
join(
"The Byte Buddy agent cannot be loaded.",
"",
"To initialise the Byte Buddy agent, a subprocess may need to be created. To do this, the JVM requires "
+ "knowledge of the 'os.name' System property in most JRE implementations. This property is not present, "
+ "which means this operation will fail to complete. Please first make sure you are not clearing this "
+ "property anywhere, and failing that, raise a bug with your JVM vendor."));
}
try {
try {
instrumentation = ByteBuddyAgent.install();
if (!instrumentation.isRetransformClassesSupported()) {
throw new IllegalStateException(
join(
"Byte Buddy requires retransformation for creating inline mocks. This feature is unavailable on the current VM.",
"",
"You cannot use this mock maker on this VM"));
}
File boot = File.createTempFile("mockitoboot", ".jar");
boot.deleteOnExit();
JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(boot));
try {
String source =
"org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher";
InputStream inputStream =
InlineDelegateByteBuddyMockMaker.class
.getClassLoader()
.getResourceAsStream(source + ".raw");
if (inputStream == null) {
throw new IllegalStateException(
join(
"The MockMethodDispatcher class file is not locatable: "
+ source
+ ".raw",
"",
"The class loader responsible for looking up the resource: "
+ InlineDelegateByteBuddyMockMaker.class
.getClassLoader()));
}
outputStream.putNextEntry(new JarEntry(source + ".class"));
try {
int length;
byte[] buffer = new byte[1024];
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
} finally {
inputStream.close();
}
outputStream.closeEntry();
} finally {
outputStream.close();
}
try (JarFile jarfile = new JarFile(boot)) {
instrumentation.appendToBootstrapClassLoaderSearch(jarfile);
}
try {
Class.forName(
"org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher",
false,
null);
} catch (ClassNotFoundException cnfe) {
throw new IllegalStateException(
join(
"Mockito failed to inject the MockMethodDispatcher class into the bootstrap class loader",
"",
"It seems like your current VM does not support the instrumentation API correctly."),
cnfe);
}
} catch (IOException ioe) {
throw new IllegalStateException(
join(
"Mockito could not self-attach a Java agent to the current VM. This feature is required for inline mocking.",
"This error occured due to an I/O error during the creation of this agent: "
+ ioe,
"",
"Potentially, the current VM does not support the instrumentation API correctly"),
ioe);
}
} catch (Throwable throwable) {
instrumentation = null;
initializationError = throwable;
}
INSTRUMENTATION = instrumentation;
INITIALIZATION_ERROR = initializationError;
}
private final BytecodeGenerator bytecodeGenerator;
private final WeakConcurrentMap