Java 通过MySQL直接重新序列化JBPM过程变量

Java 通过MySQL直接重新序列化JBPM过程变量,java,mysql,jbpm,Java,Mysql,Jbpm,我正在使用一个使用JBPM 3.1和MySQL的应用程序。核心问题是,有些流程实例的变量包含外部非JBPMSerializable类的旧版本。升级主应用程序时,这些进程实例会导致JBPM引发异常,因为主应用程序中特定类实例的SUID已更改 我相信我有一种方法可以使用下面描述的技术修复反序列化过程: 然而,我的问题是找出在MySQL中JBPM存储流程实例变量的位置,这样我就可以编写一个程序,可以对所有实例的所有变量进行交互,重新序列化变量,使违规类具有新的SUID,这样JBPM就可以对流程进行操

我正在使用一个使用JBPM 3.1和MySQL的应用程序。核心问题是,有些流程实例的变量包含外部非JBPM
Serializable
类的旧版本。升级主应用程序时,这些进程实例会导致JBPM引发异常,因为主应用程序中特定类实例的SUID已更改

我相信我有一种方法可以使用下面描述的技术修复反序列化过程:

然而,我的问题是找出在MySQL中JBPM存储流程实例变量的位置,这样我就可以编写一个程序,可以对所有实例的所有变量进行交互,重新序列化变量,使违规类具有新的SUID,这样JBPM就可以对流程进行操作

我最初查看JBPM表时发现,JBPM_BYTEARRAY和/或JBPM_BYTEBLOCK可能是要操作的表。然而,我不确定如何继续。我猜每个流程变量都存储在包装容器类中。那个类是
org.jbpm.context.exe.VariableInstance
?还是别的什么


我想如果我在类路径中有正确的jar文件,并且我知道JBPM在MySQL中存储过程变量的主要类实例是什么,我可以反序列化该类(这将修复嵌入问题类实例的SUID问题),然后重新序列化该类。由于JBPM文档确实提到了转换器的相关内容,我不确定在反序列化时是否必须复制JPBM所做的转换过程,或者标准java反序列化是否足够。

您知道您所做的更改是否违反了约定,或者只是简单地添加了新字段?如果只是添加新字段,那么只需定义Previor serialversionuid。。否则。。您必须读取所有具有不同SerialVersionID的变量,并将它们保存在新类下,因为您是唯一知道如何转换它们的人。

您知道您所做的更改是否违反了约定,或者只是简单地添加了新字段?如果只是添加新字段,那么只需定义Previor serialversionuid。。否则。。您必须读取所有具有不同SerialVersionID的变量,并将它们保存在新类下,因为您是唯一知道如何转换它们的人。

对JBPM的一些分析表明,二进制数据可能会被拆分到多个记录中。mysql本身可能不是这样,但JPBM代码是为支持多个RDBMs而编写的,有些代码对二进制记录的大小有限制

由于这个问题为我赢得了风滚草奖,我无法在我必须满足的期限内得到一个基于mysql的可用答案,因此我重新考虑了核心问题和出现问题的操作环境,并提出了一个解决方案,避免了执行直接mysql操作所需的时间

讨论中的主要应用程序已经对JBPM进行了一些定制修改,因此我实现的解决方案改变了JBPM源代码,它执行流程实例变量的反序列化。这避免了需要处理从RDBMs提取反序列化二进制数据的JBPM逻辑

在类
org.jbpm.context.exe.converter.SerializableToByteArrayConverter
中,我修改了代码以使用自定义
ObjectInputStream
类,该类返回类的最新SUID。如果新类包含新字段,则仅使用问题中引用的post中描述的类的最新版本替换描述符的技术不起作用。这样做会导致数据结束异常,因为基本反序列化代码尝试访问类的旧反序列化版本中的“新”字段

因此,我只需要替换SUID,但保持描述符的所有其他部分相同。由于JDK没有使
ObjectStreamClass
可扩展,因此我创建了
ObjectInputStream
的子类,该子类根据java库在反序列化数据时针对
ObjectInputStream
执行的给定调用模式返回新的SUID

模式:读取反序列化对象的头时,调用
readUTF()
函数(以获取类名),然后调用
readLong()。因此,如果发生此调用序列,并且如果
readUTF()
返回了我想要更改的SUID的类名,我将在
readLong()
调用中返回较新的SUID

自定义代码读取一个配置文件,该文件指定应映射到所列类的最新SUID的类名和关联的SUID。这允许将来在不修改自定义代码的情况下映射备用类


注意,此方法适用于一般反序列化操作,其中需要将旧SUID映射到指定类的最新SUID,如果较新的类定义包含旧的类定义中不存在的其他字段声明,则保留序列化类描述符的其他部分以避免数据结束问题。

对JBPM的一些分析表明,二进制数据可能会被拆分到多个记录中。mysql本身可能不是这样,但JPBM代码是为支持多个RDBMs而编写的,有些代码对二进制记录的大小有限制

由于这个问题为我赢得了风滚草奖,我无法在我必须满足的期限内得到一个基于mysql的可用答案,因此我重新考虑了核心问题和出现问题的操作环境,并提出了一个解决方案,避免了执行直接mysql操作所需的时间

讨论中的主要应用程序已经对JBPM进行了一些自定义修改,因此我实现的解决方案改变了JBPM源代码,该源代码执行