public java.lang.Object writeReplace(java.lang.Object mockitoMock) throws java.io.ObjectStreamException
writeReplace
method for serialization.
Here's how it's working and why :
When first entering in this method, it's because some is serializing the mock, with some code like :
objectOutputStream.writeObject(mock);
So, ObjectOutputStream
will track the writeReplace
method in the instance and
execute it, which is wanted to replace the mock by another type that will encapsulate the actual mock.
At this point, the code will return an
AcrossJVMSerializationFeature.AcrossJVMMockSerializationProxy
.
Now, in the constructor
org.mockito.internal.creation.AcrossJVMSerializationFeature.AcrossJVMMockSerializationProxy#AcrossJVMMockSerializationProxy(Object)
the mock is being serialized in a custom way (using
AcrossJVMSerializationFeature.MockitoMockObjectOutputStream
) to a
byte array. So basically it means the code is performing double nested serialization of the passed
mockitoMock
.
However the ObjectOutputStream
will still detect the custom
writeReplace
and execute it.
(For that matter disabling replacement via ObjectOutputStream.enableReplaceObject(boolean)
doesn't disable the writeReplace
call, but just just toggle replacement in the
written stream, writeReplace
is always called by
ObjectOutputStream
.)
In order to avoid this recursion, obviously leading to a StackOverflowError
, this method is using
a flag that marks the mock as already being replaced, and then shouldn't replace itself again.
This flag is local to this class, which means the flag of this class unfortunately needs
to be protected against concurrent access, hence the reentrant lock.
java.io.ObjectStreamException
boolean instanceLocalCurrentlySerializingFlag
java.util.concurrent.locks.Lock mutex
private java.lang.Object readResolve() throws java.io.ObjectStreamException
Uses the custom crafted AcrossJVMSerializationFeature.MockitoMockObjectInputStream
to deserialize the mock.
java.io.ObjectStreamException
byte[] serializedMock
java.lang.Class<T> typeToMock
java.util.Set<E> extraInterfaces
InternalMockHandler<T> handler
CGLIBHacker cglibHacker
ObjectMethodsGuru objectMethodsGuru
MockCreationSettings<T> mockSettings
AcrossJVMSerializationFeature acrossJVMSerializationFeature
java.lang.Class<T> typeToMock
java.util.Set<E> extraInterfaces
java.lang.String name
java.lang.Object spiedInstance
Answer<T> defaultAnswer
MockName mockName
SerializableMode serializableMode
java.util.List<E> invocationListeners
boolean stubOnly
java.lang.Throwable stackTraceHolder
StackTraceFilter stackTraceFilter
IMockitoConfiguration config
StackTraceFilter filter
int sequenceNumber
java.lang.Object mock
MockitoMethod method
java.lang.Object[] arguments
java.lang.Object[] rawArguments
Location location
boolean verified
boolean isIgnoredForVerification
RealMethod realMethod
StubInfo stubInfo
Invocation invocation
java.util.List<E> matchers
java.lang.Class<T> declaringClass
java.lang.String methodName
java.lang.Class<T>[] parameterTypes
java.lang.Class<T> returnType
java.lang.Class<T>[] exceptionTypes
boolean isVarArgs
boolean isAbstract
DescribedInvocation stubbedAt
MockitoMethodProxy methodProxy
RealMethod realMethod
org.hamcrest.Matcher<T> actualMatcher
Location location
java.util.LinkedList<E> stubbed
MockingProgress mockingProgress
java.util.List<E> answersForStubbing
RegisteredInvocations registeredInvocations
InvocationMatcher invocationForStubbing
java.util.Queue<E> answers
DescribedInvocation usedAt
ReturnValues returnValues
java.lang.Throwable throwable
ConditionalStackTraceFilter filter
java.lang.Class<T> throwableClass
ConditionalStackTraceFilter filter
ObjectMethodsGuru methodsGuru
MockUtil mockUtil
MockitoCore mockitoCore
Answer<T> delegate
Invocation invocation