背景:我们正在使用Activiti作为流程引擎,使用Activiti-Rest作为接口与我们的应用程序进行交互。由于问题涉及到REST服务返回由Java序列化的对象,所以我没有将其添加到标题中。
场景:我们有一个包含模块(我们称之为X)的JBoss Wildfly实例,该模块包含一个名为“ProcessContext”的类。Activiti在此EAR内运行,并且ServiceTasks(从流程中调用的Java代码段来执行一些任务)依赖于该类。它们使用此类来实例化流程变量并向其中添加一些数据。
我们有第二个部署(一个WAR,当前在同一台Wildfly实例上,但稍后移到远程服务器上),通过其REST API访问Activiti,并且现在我们需要访问“ProcessContext”数据。这个WAR也依赖于X,并且其类加载器可以轻松解析“ProcessContext”。
好的,很好。这似乎很简单。调用:
GET history/historic-process-instances/{processInstanceId}/variables/{variableName}/data
这将返回一个媒体类型为"application/x-java-serialized-object"的响应,使用调试器检查似乎没有问题。但是当我试图反序列化对象时,却遇到了以下错误:
Caused by: java.lang.ClassNotFoundException: xxx.commons.metadata.ProcessMetadata from [Module "org.jboss.resteasy.resteasy-jaxrs:main" from local module loader @103f852 (finder: local module finder @587c290d (roots: /opt/wildfly/modules,/opt/wildfly/modules/system/layers/base))]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:213) [jboss-modules.jar:1.3.3.Final]
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:459) [jboss-modules.jar:1.3.3.Final]
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:408) [jboss-modules.jar:1.3.3.Final]
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:389) [jboss-modules.jar:1.3.3.Final]
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:134) [jboss-modules.jar:1.3.3.Final]
at java.lang.Class.forName0(Native Method) [rt.jar:1.8.0_20]
at java.lang.Class.forName(Class.java:340) [rt.jar:1.8.0_20]
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:626) [rt.jar:1.8.0_20]
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1613) [rt.jar:1.8.0_20]
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518) [rt.jar:1.8.0_20]
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774) [rt.jar:1.8.0_20]
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351) [rt.jar:1.8.0_20]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371) [rt.jar:1.8.0_20]
at org.jboss.resteasy.plugins.providers.SerializableProvider.readFrom(SerializableProvider.java:76) [resteasy-jaxrs-3.0.10.Final.jar:]
... 131 more
我发现,如果使用的是 Resteasy 模块的 Module-Classloader 而不是本地(模块)类加载器,则用于反序列化对象的 Classloader 会出现问题。
可能的解决方案之一是编写一个包含“ProcessContext”的模块,并使其在 JBoss 中全局可用,但该项目的负责人否决了这个基础设施决策。
难道 Resteasy 不应该使用调用者的类加载器而不是其模块类加载器吗?调用者知道其所需的类,如果我能够获取响应的内部输入流,我就可以自己进行反序列化而不会出现任何问题。我真的很想知道这是一个错误还是一个特性。
有什么解决这个问题的想法吗?