Hi,I'm using activiti in a Grails project and having trouble when it comes to deserializing Groovy objects that are stored in process variables. I'm experiencing pretty much the same problems as described in this post (not using the Grails Avticiti plugin, though): http://code.google.com/p/grails-activiti-plugin/issues/detail?id=16To sum it up, deserializing my objects fails with a ClassNotFoundException, which is due to the wrong ClassLoader being used.I came up with a workaround employing the suggested solution from http://jira.codehaus.org/browse/GROOVY-1627, which is to subclass ObjectInputStream and overriding the resolveClass method in order to use a specific class loader (in my case the grailsApplication.classLoader). The workaround seems to work but it is rather ugly and I am wondering, if there is a better solution to my problem.Here's my approach: In order to tap into the process of deserializing process variables, I subclass the Activiti SerializableType and override the getValue method, which is the place where deserialization happens. I basically copy-pasted the SerializableType's implementation an replaced the ObjectInputStream with my custom implementation. During application startup I register my custom SerializableType with the ProcessEngineConfiguration.Here's my Grails service that does all that: class CustomSerializableProcessTypeService {
static transactional = false
ProcessEngineConfigurationImpl processEngineConfiguration
def grailsApplication
void registerCustomSerializableType () {
processEngineConfiguration.variableTypes.addType (new CustomSerializableType (), 0)
}
class CustomSerializableType extends SerializableType {
@Override
Object getValue (ValueFields valueFields) {
Object cachedObject = valueFields.getCachedValue ();
if (cachedObject != null) {
return cachedObject;
}
byte[] bytes = valueFields.getByteArrayValue ()?.getBytes ();
ByteArrayInputStream bais = new ByteArrayInputStream (bytes);
Object deserializedObject = null;
try {
ObjectInputStream ois = new CustomObjectInputStream (bais) // <=== This is the line of interest
deserializedObject = ois.readObject ();
valueFields.setCachedValue (deserializedObject);
if (valueFields instanceof VariableInstanceEntity) {
Context.
getCommandContext ().
getDbSqlSession ().
addDeserializedObject (deserializedObject, bytes, (VariableInstanceEntity) valueFields);
}
} catch (Exception e) {
log.warn ("exception occurred in getValue of custom SerializableType, trying super class", e)
} finally {
IoUtil.closeSilently (bais);
}
if (deserializedObject) {
return deserializedObject;
}
return super.getValue (valueFields)
}
}
class CustomObjectInputStream extends ObjectInputStream {
CustomObjectInputStream (InputStream inputStream) {
super(inputStream)
}
protected Class resolveClass (ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
return Class.forName (objectStreamClass.getName (), true, grailsApplication.classLoader);
}
}
}So here are my questions:1. Is there a better way fix the ClassLoader issue?2. If not, is there a better way to register custom VariableTypes? I'm currently using the ProcessEngineConfigurationImpl's VaraibleTypes object, which isn't even exposed by the ProcessEngineConfiguration interface. (By the way, I'm having a hard time to find documentation on this.)I appreciate any hints! Thanks a lotDaniel