[
https://jira.jboss.org/jira/browse/JBPM-1914?page=com.atlassian.jira.plug...
]
Mauro Molinari commented on JBPM-1914:
--------------------------------------
Hi Ronald, I don't want to make this report go off-topic, however please consider that
we're not storing domain model objects nor complex things in the jBPM database, but
very simple instances of a serializable wrapper object that is needed to store a navigable
(simple) structure we need to save together with our process instances. So, it is done on
purpose and not because of a bad practice in jBPM usage... Consider also that this is
needed to overcome a (serious, IMHO) limitation in jBPM design, that is the lack of
support to rebuild the "past" of the process instance flow.
Problem in retrieving variables of Serializable objects
-------------------------------------------------------
Key: JBPM-1914
URL:
https://jira.jboss.org/jira/browse/JBPM-1914
Project: JBoss jBPM
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: Core Engine
Affects Versions: jBPM 3.3.0 GA
Reporter: Mauro Molinari
Priority: Critical
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)
{
final LazyInitializer initializer =
((HibernateProxy) proxy).getHibernateLazyInitializer();
return initializer.getImplementation();
}
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
{
result =
new ObjectInputStream(new ByteArrayInputStream(((ByteArray) result)
.getBytes())).readObject();
}
catch(final Exception e)
{
throw new RuntimeException(e);
}
return result;
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira