AnsweredAssumed Answered

Variable serialization & Class Loading

Question asked by oefimov on Aug 13, 2014
Latest reply on Aug 30, 2014 by jbarrez
AFAIK Activiti Engine offers class loading extension point by the following means:
  • Developer can provide custom class loader by setting
    classLoader
    property of
    org.activiti.engine.ProcessEngineConfiguration
    ;
  • Custom class loader may refer to the
    org.activiti.engine.impl.context.Context.getExecutionContext().getProcessDefinition().getDeploymentId()
    method for deployment context.
However, if you want to use variables in you process instance of types defined in the per-deployment class loader, you'll find yourself in trouble: Activiti Engine will call your class loader without providing context information.

This can be seen in class
org.activiti.engine.impl.variable.SerializableType
:

  protected ObjectInputStream createObjectInputStream(InputStream is) throws IOException {
    return new ObjectInputStream(is) {
      protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        return ReflectUtil.loadClass(desc.getName());
      }
    };
  }

No context information is set here before loading the class.

Even if core team decides to abandon this request, I would like to extend core behaviour with providing deployment context  in se/deserialization.

However, overriding this behaviour is cumbersome since classes
org.activiti.engine.impl.variable.SerializableType
and
org.activiti.engine.impl.variable.DeserializedObject
are rather poorly designed:
  • it's hard to override
    org.activiti.engine.impl.variable.SerializableType.createObjectOutputStream
    , since it's private static – you have to copy/paste entire methods calling it. Its fellow method createObjectInputStream is protected and not static.
  • org.activiti.engine.impl.variable.DeserializedObject.flush()
    uses static method mentioned above, you have to overrride the entire method and also override methods containing creation of deserialized object in
    org.activiti.engine.impl.variable.SerializableType
    . I would suggest deserialized object calling callback method for serialization in the creating object, which is subject to overriding.

Outcomes