使用Kyro / Activiti和Spring Integration获得ConcurrentModificationException

时间:2016-09-10 21:29:22

标签: spring-integration activiti spring-rabbit

我正在尝试将Activiti与Spring Integration集成。 Josh Long提供的示例有效但当我尝试更改它时,特别是MessageChannels部分,它开始抛出ConcurrentModificationException

Josh Longs Activiti/Spring Integration example在这里。

根据Josh的代码,MessageChannels如下:

@Configuration
class MessageChannels {

    @Bean
    DirectChannel requests() {
        return new DirectChannel();
    }

    @Bean
    DirectChannel replies() {
        return new DirectChannel();
    }
}

我将此更改为spring integration(使用Stream Rabbit)

@Configuration
public interface MessageChannels {

    @Input
    SubscribableChannel input();

    @Output("cooutput")
    MessageChannel createOutput();

}

我的属性文件包含,

spring.cloud.stream.bindings.cooutput.destination=outputChannel

当我打电话给“/ start”时,我得到以下异常。

2016-09-10 16:14:39.087  INFO 73606 --- [           main] c.e.ActivitiIntegrationDemoApplication   : Started ActivitiIntegrationDemoApplication in 8.236 seconds (JVM running for 8.759)
2016-09-10 16:15:39.524  INFO 73606 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2016-09-10 16:15:39.524  INFO 73606 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2016-09-10 16:15:39.540  INFO 73606 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 16 ms
2016-09-10 16:15:39.598  INFO 73606 --- [nio-8080-exec-1] o.s.i.codec.kryo.CompositeKryoRegistrar  : registering [40, java.io.File] with serializer org.springframework.integration.codec.kryo.FileSerializer
2016-09-10 16:15:39.638 ERROR 73606 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.cloud.stream.binder.rabbit.RabbitMessageChannelBinder$SendingHandler@1b59052b]; nested exception is com.esotericsoftware.kryo.KryoException: java.util.ConcurrentModificationException
Serialization trace:
classes (sun.misc.Launcher$AppClassLoader)
beanClassLoader (org.springframework.context.event.SimpleApplicationEventMulticaster)
applicationEventMulticaster (org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext)
applicationContext (org.activiti.spring.ApplicationContextElResolver)
resolvers (org.activiti.engine.impl.javax.el.CompositeELResolver)
elResolver (org.activiti.engine.impl.el.ActivitiElContext)
cachedElContext (org.activiti.engine.impl.persistence.entity.ExecutionEntity)] with root cause

java.util.ConcurrentModificationException: null
    at java.util.Vector$Itr.checkForComodification(Vector.java:1184) ~[na:1.8.0_102]
    at java.util.Vector$Itr.next(Vector.java:1137) ~[na:1.8.0_102]
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:92) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:40) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:552) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:80) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:518) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:552) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:80) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:518) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:552) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:80) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:518) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:552) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:80) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:518) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:628) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:100) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:40) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:552) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:80) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:518) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:552) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:80) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:518) ~[kryo-shaded-3.0.3.jar:na]
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:552) ~[kryo-shaded-3.0.3.jar:na]
    at 

我还在主类中添加了以下注释。

@SpringBootApplication
@IntegrationComponentScan
@EnableBinding(MessageChannels.class)

1 个答案:

答案 0 :(得分:0)

不确定如何帮助您,因为您的用例完全不清楚,但您对Activiti中某些不可序列化的对象的序列化存在问题。 看起来那个ActivityExecution方法中的execute()个实例。

Activiti-Spring Integration示例做了类似的事情:

  1. 通过/start REST端点启动该过程。

  2. 该进程通过gateway bean - ReceiveTaskActivityBehavior进行Spring Integration的委派。它的JavaDocs说:

    * A receive task is a wait state that waits for the receival of some message.
    * 
    * Currently, the only message that is supported is the external trigger,
    * given by calling the {@link RuntimeService#signal(String)} operation.
    
  3. 所以,execute() impl只是表明我们可以调用Spring Integration。主要部分保持不变 - 暂停该过程,直到signal()MessageChannels.replies() REST端点完成/resume

    1. 现在,请解释一下,您希望通过Spring Cloud Stream实现目标。实际上,此Activiti示例中的requests()/replies()input都是/start。您可以通过/resume/start REST API在应用中发起一些事情。
    2. 不确定您是如何修改该示例的,但new DataRegister.add(someting); new DataRegister.getData(); 启动发送给RabbitMQ Binder的消息真的很奇怪......