Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-10802

java.lang.ClassCastException when using FlexibleAggregationStrategy with Spring Boot

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 2.18.2
    • Fix Version/s: 2.18.3, 2.19.0
    • Labels:
      None
    • Environment:

      Windows 10
      Camel 2.18.2
      Spring 4.3.6
      Spring Boot 1.5.1

    • Estimated Complexity:
      Unknown

      Description

      We are having a strange issue while using the FlexibleAggregationStrategy
      with spring boot. Below is a sample and trivial route I just made up
      to demonstrate the issue:

      from("direct:should-work")
                      .id("should-work")
                      .log(LoggingLevel.INFO, "Before the first split the
      body is ${body} and has class ${body.getClass()}")
                      .split(body(),
      AggregationStrategies.flexible().pick(body()).accumulateInCollection(LinkedList.class))
                      .log(LoggingLevel.INFO, "During the first split the
      body is ${body} and has class ${body.getClass()}")
                      .end()
                      .log(LoggingLevel.INFO, "Before the second split the
      body is ${body} and has class ${body.getClass()}")
                      .split(body(),
      AggregationStrategies.flexible().pick(body()).accumulateInCollection(LinkedList.class))
                      .log(LoggingLevel.INFO, "During the second split the
      body is ${body} and has class ${body.getClass()}")
                      .end()
                      .log(LoggingLevel.INFO, "After the second split the
      body is ${body} and has class ${body.getClass()}")
      
      

      Along with the relevant unit test:

         @Test
          public void shouldProduceMessages() throws InterruptedException {
              // we expect that a number of messages is automatic done by the Camel
              // route as it uses a timer to trigger
              NotifyBuilder notify = new
      NotifyBuilder(camelContext).whenDone(1).and().whenExactlyFailed(0).create();
      
              producerTemplateShouldWork.sendBody(Arrays.asList("FIRST", "SECOND"));
      
              assertTrue(notify.matches(10, TimeUnit.SECONDS));
          }
      

      The test fails with the following unexpected exception:

      java.lang.ClassCastException: Cannot cast java.util.LinkedHashSet to
      java.util.LinkedList
      at java.lang.Class.cast(Class.java:3369) ~[na:1.8.0_111]
      at org.apache.camel.util.toolbox.FlexibleAggregationStrategy.safeInsertIntoCollection(FlexibleAggregationStrategy.java:281)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.util.toolbox.FlexibleAggregationStrategy.injectAsCollection(FlexibleAggregationStrategy.java:264)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.util.toolbox.FlexibleAggregationStrategy.aggregate(FlexibleAggregationStrategy.java:235)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.MulticastProcessor.doAggregateInternal(MulticastProcessor.java:942)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.MulticastProcessor.doAggregate(MulticastProcessor.java:924)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:644)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:238)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.Splitter.process(Splitter.java:108)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:542)
      ~[camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:529)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:497)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:365)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:497)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:225)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:144)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:161)
      [camel-core-2.18.2.jar:2.18.2]
      at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:370)
      [camel-core-2.18.2.jar:2.18.2]
      at broken.MySpringBootRouterTest.shouldProduceMessages(MySpringBootRouterTest.java:41)
      [test-classes/:na]
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      ~[na:1.8.0_111]
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      ~[na:1.8.0_111]
      at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
      [junit-4.12.jar:4.12]
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      [junit-4.12.jar:4.12]
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
      [junit-4.12.jar:4.12]
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      [junit-4.12.jar:4.12]
      at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
      [spring-test-4.3.6.RELEASE.jar:4.3.6.RELEASE]
      at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
      [spring-test-4.3.6.RELEASE.jar:4.3.6.RELEASE]
      at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
      [spring-test-4.3.6.RELEASE.jar:4.3.6.RELEASE]
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
      [junit-4.12.jar:4.12]
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
      [spring-test-4.3.6.RELEASE.jar:4.3.6.RELEASE]
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
      [spring-test-4.3.6.RELEASE.jar:4.3.6.RELEASE]
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      [junit-4.12.jar:4.12]
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      [junit-4.12.jar:4.12]
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      [junit-4.12.jar:4.12]
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      [junit-4.12.jar:4.12]
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      [junit-4.12.jar:4.12]
      at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      [spring-test-4.3.6.RELEASE.jar:4.3.6.RELEASE]
      at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
      [spring-test-4.3.6.RELEASE.jar:4.3.6.RELEASE]
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      [junit-4.12.jar:4.12]
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
      [spring-test-4.3.6.RELEASE.jar:4.3.6.RELEASE]
      at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12]
      at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
      [junit-rt.jar:na]
      at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
      [junit-rt.jar:na]
      at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
      [junit-rt.jar:na]
      at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
      [junit-rt.jar:na]
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      ~[na:1.8.0_111]
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      ~[na:1.8.0_111]
      at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
      [idea_rt.jar:na]
      

      And from the log we can see that it has failed at the second aggregate
      step of the route.
      Just for fun, I've also tried changing the second aggregation to
      produce HashSet, and here's the resulting exchange:

      [Message[ID-CAMERA-GIO-51647-1486214369840-0-21], SECOND, FIRST]
      

      So it looks like either spring or camel are trying to aggregate back
      into an HashSet of messages instead of an empty one

      If anyone wants to have a deeper look, I've put online a small test
      project here:

      https://gitlab.com/g.condello/camel-split-join-issue

        Attachments

          Activity

            People

            • Assignee:
              davsclaus Claus Ibsen
              Reporter:
              gcotgi Giovanni Condello
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: