[
https://jira.jboss.org/jira/browse/JBPM-2692?page=com.atlassian.jira.plug...
]
Mauro Molinari updated JBPM-2692:
---------------------------------
Attachment: patch_for_JBPM-2692.txt
Here is my proposed patch. This is the idea behind it:
- I created a new extension of ContextConverter called ProcessDefinitionContextConverter
which overloads revert to accept also a ProcessDefinition instead of a Token
- SerializableToByteArrayConverter now implements PorcessDefinitionContextConverter and
uses the process definition to do deserialization
- I added a column to table JBPM_VARIABLEINSTANCE called PROCESSDEFINITION_ wich is a
foreign key to JBPM_PROCESSDEFINITION
- when a VariableInstance is created, the processDefinition field is initialized along
with the token and processInstance fields, so that it is stored in the database
- when a VariableInstance is deleted, its references to the token and the process instance
are removed, but not the reference to the process definition
- VariableInstance.getValue() now does the following:
1) if the converter is a ContextConverter and the token is not null (richest
information), use org.jbpm.context.exe.ContextConverter.revert(Object, Token) method
2) otherwise, if the converter is a ProcessDefinitionConverter and the processDefinition
is not null (this check is for retro-compatibility), use
org.jbpm.context.exe.ProcessDefinitionContextConverter.revert(Object, ProcessDefinition)
3) otherwise use org.jbpm.context.exe.Converter.revert(Object) (no process-related
context information at all)
In this way, the code should be perfectly retro-compatible and the only mandatory data
migration needed is the addition of the (still nullable) column
JBPM_VARIABLEINSTANCE.PROCESSDEFINITION_.
Please note that the given patch does not update the SQL scripts provided in /database
folder o jBPM distribution.
Here are a couple of scripts needed to migrate the database:
FIRST SCRIPT (MANDATORY): add column JBPM_VARIABLEINSTACE.PROCESSDEFINITION_
--- PostgreSQL ---
ALTER TABLE JBPM_VARIABLEINSTANCE
ADD COLUMN PROCESSDEFINITION_ INT8;
ALTER TABLE JBPM_VARIABLEINSTANCE
ADD CONSTRAINT FK_VARINST_PRCDEF
FOREIGN KEY (PROCESSDEFINITION_)
REFERENCES JBPM_PROCESSDEFINITION;
--- Oracle ---
ALTER TABLE JBPM_VARIABLEINSTANCE
ADD PROCESSDEFINITION_ NUMBER(19,0);
ALTER TABLE JBPM_VARIABLEINSTANCE
ADD CONSTRAINT FK_VARINST_PRCDEF
FOREIGN KEY (PROCESSDEFINITION_)
REFERENCES JBPM_PROCESSDEFINITION;
SECOND SCRIPT (OPTIONAL): populate the new column with the correct data; if you do not do
that, jBPM behaves exactly the same as it would do without the patch applied (so this bug
will occur, but no additional harm)
--- PostgreSQL / Oracle ---
UPDATE JBPM_VARIABLEINSTANCE
SET PROCESSDEFINITION_=
(SELECT PROCESSDEFINITION_
FROM JBPM_PROCESSINSTANCE, JBPM_TOKEN
WHERE JBPM_TOKEN.PROCESSINSTANCE_=JBPM_PROCESSINSTANCE.ID_
AND JBPM_TOKEN.ID_=JBPM_VARIABLEINSTANCE.TOKEN_)
WHERE TOKEN_ IS NOT NULL;
UPDATE JBPM_VARIABLEINSTANCE
SET PROCESSDEFINITION_=
(SELECT DISTINCT PROCESSDEFINITION_
FROM JBPM_PROCESSINSTANCE, JBPM_TOKEN, JBPM_LOG
WHERE JBPM_TOKEN.PROCESSINSTANCE_=JBPM_PROCESSINSTANCE.ID_
AND JBPM_LOG.TOKEN_=JBPM_TOKEN.ID_
AND JBPM_LOG.VARIABLEINSTANCE_=JBPM_VARIABLEINSTANCE.ID_)
WHERE TOKEN_ IS NULL;
That's it. I hope this is of help for you.
Still problems with variables of Serializable objects
-----------------------------------------------------
Key: JBPM-2692
URL:
https://jira.jboss.org/jira/browse/JBPM-2692
Project: jBPM
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: Runtime Engine
Affects Versions: jBPM 3.2.6.SP1
Environment: jBPM 3.2.6.SP1 embedded into a web application
Reporter: Mauro Molinari
Attachments: patch_for_JBPM-2692.txt
There are times in which when calling org.jbpm.context.exe.VariableInstance.getValue(),
the proprty token is null. In this case, if the variable object is of a Serializable class
and this class is in the PAR, calling getValue() will fail with a ClassNotFound exception
if the process class loader is not the one who loaded the SerializableToByteArrayConverter
class. This is because the method
org.jbpm.context.exe.converter.SerializableToByteArrayConverter.revert(ByteArray) (without
the token) is called and a plain ObjectInputStream is used to do the deserialization.
I don't have a simple test case to reproduce, but this is what I am doing:
- my webapp application is retreiving all the logs associated to a ProcessInstance using
org.jbpm.db.LoggingSession.findLogsByProcessInstance(long)
- it is iterating over the collection and, for each ProcessLog instance, it is retreiving
the variable instance values (for example: org.jbpm.context.log.VariableCreateLog the
method org.jbpm.context.log.VariableLog.getVariableInstance() is called; for a
org.jbpm.context.log.VariableUpdateLog the methods
org.jbpm.context.log.VariableUpdateLog.getOldValue() and
org.jbpm.context.log.VariableUpdateLog.getNewValue() are called and so on)
- a ClassNotFoundException is launched; the class loader in use is that of the webapp, so
it's normal that the class of the variable value cannot be found, since it is a
serializable class provided by the PAR.
I don't know why token is null: should it be restored by Hibernate? Looking at
org.jbpm.context.exe.VariableInstance the only explicit code that sets the token property
is in org.jbpm.context.exe.VariableInstance.create(Token, String, Object).
--
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