@Incubating class ByteBuddyCrossClassLoaderSerializationSupport extends java.lang.Object implements java.io.Serializable
Serializable
.
The way it works is to enable serialization with mode SerializableMode.ACROSS_CLASSLOADERS
,
if the mock settings is set to be serializable the mock engine will implement the
ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializableMock
marker interface.
This interface defines a the ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializableMock.writeReplace()
whose signature match the one that is looked by the standard Java serialization.
Then in the proxy class there will be a generated writeReplace
that will delegate to
MockMethodInterceptor.ForWriteReplace.doWriteReplace(MockAccess)
of mockito, and in turn will delegate to the custom
implementation of this class writeReplace(Object)
. This method has a specific
knowledge on how to serialize a mockito mock that is based on ByteBuddy and will ignore other Mockito MockMakers.
Only one instance per mock! See MockMethodInterceptor
SubclassByteBuddyMockMaker
,
MockMethodInterceptor
Modifier and Type | Class and Description |
---|---|
static interface |
ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializableMock
Simple interface that hold a correct
writeReplace signature that can be seen by an
ObjectOutputStream . |
static class |
ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializationProxy
This is the serialization proxy that will encapsulate the real mock data as a byte array.
|
static class |
ByteBuddyCrossClassLoaderSerializationSupport.MockitoMockObjectInputStream
Special Mockito aware
ObjectInputStream that will resolve the Mockito proxy class. |
private static class |
ByteBuddyCrossClassLoaderSerializationSupport.MockitoMockObjectOutputStream
Special Mockito aware
ObjectOutputStream . |
Modifier and Type | Field and Description |
---|---|
private boolean |
instanceLocalCurrentlySerializingFlag |
private static java.lang.String |
MOCKITO_PROXY_MARKER |
private java.util.concurrent.locks.Lock |
mutex |
private static long |
serialVersionUID |
Constructor and Description |
---|
ByteBuddyCrossClassLoaderSerializationSupport() |
Modifier and Type | Method and Description |
---|---|
private boolean |
mockIsCurrentlyBeingReplaced() |
private void |
mockReplacementCompleted() |
private void |
mockReplacementStarted() |
java.lang.Object |
writeReplace(java.lang.Object mockitoMock)
Custom implementation of the
writeReplace method for serialization. |
private static final long serialVersionUID
private static final java.lang.String MOCKITO_PROXY_MARKER
private boolean instanceLocalCurrentlySerializingFlag
private final java.util.concurrent.locks.Lock mutex
ByteBuddyCrossClassLoaderSerializationSupport()
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
ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializableMock
.
Now, in the constructor
CrossClassLoaderSerializationProxy#CrossClassLoaderSerializationProxy(java.lang.Object)
the mock is being serialized in a custom way (using ByteBuddyCrossClassLoaderSerializationSupport.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.
mockitoMock
- The Mockito mock to be serialized.ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializationProxy
) to be serialized by the calling ObjectOutputStream.java.io.ObjectStreamException
private void mockReplacementCompleted()
private void mockReplacementStarted()
private boolean mockIsCurrentlyBeingReplaced()