-
Bug
-
Resolution: Done
-
Major
-
jBPM 3.3.0 GA
-
None
I have encountered a serious problem working with variables whose value is a serializable object.
The problem is that sometimes (not always!) an error like the following is given when retrieving a variable:
java.lang.ClassCastException: org.jbpm.bytes.ByteArray$$EnhancerByCGLIB$$cc67d06e
The code is like:
MySerializableClass obj = (MySerializableClass) contextInstance.getVariable("myVariable");
(of course, "myVariable" is a variable that I previously have set with a MySerializableClass object)
Apart from the CGLIB awful problem with proxies, even if I extract the value from the proxy with the following:
public static Object getCGLIBProxiedObject(final Object proxy)
{
if(proxy instanceof HibernateProxy)
return proxy;
}
the problem is that the variable value is retrieved as a org.jbpm.bytes.ByteArray instead of a MyClass instance!
I did some debugging and discovered that:
- in org.jbpm.context.exe.VariableContainer.getVariable(String), when org.jbpm.context.exe.VariableContainer.hasVariableLocally(String) is called, Hibernate lazily retrieves a org.jbpm.context.exe.variableinstance.ByteArrayInstance instance from the database and creates it using its empty constructor
- unfortunately, when a org.jbpm.context.exe.VariableInstance (extended by ByteArrayInstance) is constructed using its constructor, its converter instance variable remains null
- the VariableInstance converter instance variable is set to something only when a VariableInstance is created using org.jbpm.context.exe.JbpmType.newVariableInstance(), but this is not the case when a VariableInstance is lazily loaded by Hibernate; in fact, in my case, org.jbpm.context.exe.JbpmType.newVariableInstance() is never called and the converter field of my ByteArrayInstance instance is always null!
- this causes org.jbpm.context.exe.VariableInstance.getValue() to return the value given by org.jbpm.context.exe.variableinstance.ByteArrayInstance.getObject() without applying the necessary conversion (deserialization)
Please note that my variable values are stored in jBPM database in JBPM_VARIABLEINSTANCE table with the CONVERTER column correctly populated with "R".
I think this is a critical problem. By now, the only workaround I have found is to always apply the following utility method when retrieving variable values, before returning them to the client code:
public static Object extractVariableValue(final Object rawValue)
{
Object result = CardinisJbpmUtilities.getCGLIBProxiedObject(rawValue);
if(result instanceof ByteArray)
try
catch(final Exception e)
{ throw new RuntimeException(e); } return result;
}
- is blocked by
-
JBPM-1024 Serializable variables are not being deserialized when retrieved from process
- Closed