gpt4 book ai didi

java - 直接通过 MySQL 重新序列化 JBPM 流程变量

转载 作者:行者123 更新时间:2023-11-29 00:56:02 26 4
gpt4 key购买 nike

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

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

How to deserialize an object persisted in a db now when the object has different serialVersionUID

但是,我的问题是弄清楚 MySQL JBPM 存储流程实例变量的位置,这样我就可以编写一个程序,可以对所有实例的所有变量进行交互,然后重新序列化变量,这样违规的类就会有新的 SUID,因此 JBPM 可以针对流程进行操作。

我最初查看 JBPM 表时,似乎 JBPM_BYTEARRAY 和/或 JBPM_BYTEBLOCK 可能是要操作的表。但是,我不确定如何进行。我猜每个过程变量都存储在一个包装容器类中。那个类是 org.jbpm.context.exe.VariableInstance 吗?还是其他原因?

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

最佳答案

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

由于该问题为我赢得了风滚草奖励,我无法在必须满足的截止日期内获得可用的基于 mysql 的答案,因此我重新考虑了核心问题和问题出现的运行上下文,并且想出了一个解决方案,避免了执行直接 mysql 操作的需要。

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

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

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

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

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

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

关于java - 直接通过 MySQL 重新序列化 JBPM 流程变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6090542/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com