public static void invokeToData(Object serializableObject, DataOutput out) throws IOException {
    try {
      if (serializableObject instanceof BasicSerializable) {
        dsfidSerializer.invokeToData(serializableObject, out);
        return;
      }
      boolean invoked = false;
      KnownVersion v = StaticSerialization.getVersionForDataStreamOrNull(out);

      if (KnownVersion.CURRENT != v && v != null) {
        // get versions where DataOutput was upgraded
        KnownVersion[] versions = null;
        if (serializableObject instanceof SerializationVersions) {
          SerializationVersions sv = (SerializationVersions) serializableObject;
          versions = sv.getSerializationVersions();
        }
        // check if the version of the peer or diskstore is different and
        // there has been a change in the message
        if (versions != null) {
          for (KnownVersion version : versions) {
            // if peer version is less than the greatest upgraded version
            if (v.compareTo(version) < 0) {
              serializableObject.getClass().getMethod("toDataPre_" + version.getMethodSuffix(),
                  new Class[] {DataOutput.class}).invoke(serializableObject, out);
              invoked = true;
              break;
            }
          }
        }
      }

      if (!invoked) {
        ((DataSerializable) serializableObject).toData(out);
      }
    } catch (IOException io) {
      throw new ToDataException(
          "toData failed on DataSerializable " + serializableObject.getClass(), io);
    } catch (CancelException | ToDataException | GemFireRethrowable ex) {
      // Serializing a PDX can result in a cache closed exception. Just rethrow
      throw ex;
    } catch (VirtualMachineError err) {
      SystemFailure.initiateFailure(err);
      // If this ever returns, rethrow the error. We're poisoned
      // now, so don't let this thread continue.
      throw err;
    } catch (Throwable t) {
      // Whenever you catch Error or Throwable, you must also
      // catch VirtualMachineError (see above). However, there is
      // _still_ a possibility that you are dealing with a cascading
      // error condition, so you also need to check to see if the JVM
      // is still usable:
      SystemFailure.checkFailure();
      throw new ToDataException(
          "toData failed on DataSerializable " + null == serializableObject ? "null"
              : serializableObject.getClass().toString(),
          t);
    }
  }
For backward compatibility this method should be used to invoke toData on a DSFID or
DataSerializable. It will invoke the correct toData method based on the class's version
information. This method does not write information about the class of the object. When
deserializing use the method invokeFromData to read the contents of the object.

@param serializableObject the object to write
@param out the output stream.
geode-core/src/main/java/org/apache/geode/internal/InternalDataSerializer.java