Class ByteBuddyCrossClassLoaderSerializationSupport.MockitoMockObjectInputStream

java.lang.Object
java.io.InputStream
java.io.ObjectInputStream
org.mockito.internal.creation.bytebuddy.ByteBuddyCrossClassLoaderSerializationSupport.MockitoMockObjectInputStream
All Implemented Interfaces:
Closeable, DataInput, ObjectInput, ObjectStreamConstants, AutoCloseable
Enclosing class:
ByteBuddyCrossClassLoaderSerializationSupport

public static class ByteBuddyCrossClassLoaderSerializationSupport.MockitoMockObjectInputStream extends ObjectInputStream
Special Mockito aware ObjectInputStream that will resolve the Mockito proxy class.

This specifically crafted ObjectInoutStream has the most important role to resolve the Mockito generated class. It is doing so via the resolveClass(ObjectStreamClass) which looks in the stream for a Mockito marker. If this marker is found it will try to resolve the mockito class otherwise it delegates class resolution to the default super behavior. The mirror method used for serializing the mock is ByteBuddyCrossClassLoaderSerializationSupport.MockitoMockObjectOutputStream.annotateClass(Class).

When this marker is found, ByteBuddyMockMaker.createMockType(MockCreationSettings) methods are being used to create the mock class.

  • Field Details

    • typeToMock

      private final Class<?> typeToMock
    • extraInterfaces

      private final Set<Class<?>> extraInterfaces
  • Constructor Details

  • Method Details

    • resolveClass

      protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException
      Resolve the Mockito proxy class if it is marked as such.

      Uses the fields typeToMock and extraInterfaces to create the Mockito proxy class as the ObjectStreamClass doesn't carry useful information for this purpose.

      Overrides:
      resolveClass in class ObjectInputStream
      Parameters:
      desc - Description of the class in the stream, not used.
      Returns:
      The class that will be used to deserialize the instance mock.
      Throws:
      IOException
      ClassNotFoundException
    • hackClassNameToMatchNewlyCreatedClass

      private void hackClassNameToMatchNewlyCreatedClass(ObjectStreamClass descInstance, Class<?> proxyClass) throws ObjectStreamException
      Hack the name field of the given ObjectStreamClass with the newProxyClass.

      The parent ObjectInputStream will check the name of the class in the stream matches the name of the one that is created in this method.

      The CGLIB classes uses a hash of the classloader and/or maybe some other data that allow them to be relatively unique in a JVM.

      When names differ, which happens when the mock is deserialized in another ClassLoader, a java.io.InvalidObjectException is thrown, so this part of the code is hacking through the given ObjectStreamClass to change the name with the newly created class.

      Parameters:
      descInstance - The ObjectStreamClass that will be hacked.
      proxyClass - The proxy class whose name will be applied.
      Throws:
      InvalidObjectException
      ObjectStreamException
    • notMarkedAsAMockitoMock

      private boolean notMarkedAsAMockitoMock(Object marker)
      Read the stream class annotation and identify it as a Mockito mock or not.
      Parameters:
      marker - The marker to identify.
      Returns:
      true if not marked as a Mockito, false if the class annotation marks a Mockito mock.