You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (JIRA)" <ji...@apache.org> on 2016/03/09 10:58:40 UTC

[jira] [Resolved] (CAMEL-9680) Stream caching is broken under Spring Boot

     [ https://issues.apache.org/jira/browse/CAMEL-9680?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen resolved CAMEL-9680.
--------------------------------
    Resolution: Fixed

Thanks for reporting and the test.

I have fixed the type converter to not attempt converter camel stuff.

We can then consider turning off the bridge type converter all together by default if it causes more trouble.

Or if it really makes sense to have it enabled? I wonder what it brings to the table for Camel users?

> Stream caching is broken under Spring Boot
> ------------------------------------------
>
>                 Key: CAMEL-9680
>                 URL: https://issues.apache.org/jira/browse/CAMEL-9680
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-spring-boot
>    Affects Versions: 2.16.2
>            Reporter: Jostein Gogstad
>            Assignee: Claus Ibsen
>             Fix For: 2.16.3, 2.17.0
>
>
> As documented in the [camel-spring-boot documentation|https://camel.apache.org/spring-boot.html], camel-spring-boot will delegate type conversion to Spring by default (see {{org.apache.camel.spring.boot.TypeConversionConfiguration}}). Whenever the body of a route changes to a List, Spring believes it can convert it and fails. See the supplied test.
> The runs correctly if the {{SpringTypeConverter}} is removed.
> {code:java|title=StreamCachingTest.java}
> package com.example.bugs;
> import org.apache.camel.CamelContext;
> import org.apache.camel.EndpointInject;
> import org.apache.camel.builder.RouteBuilder;
> import org.apache.camel.component.mock.MockEndpoint;
> import org.apache.camel.spring.boot.SpringTypeConverter;
> import org.apache.camel.test.junit4.CamelTestSupport;
> import org.junit.Test;
> import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
> import org.springframework.context.ApplicationContext;
> import org.springframework.context.annotation.Bean;
> import org.springframework.core.convert.ConversionService;
> import org.springframework.core.convert.converter.Converter;
> import org.springframework.core.convert.support.DefaultConversionService;
> import java.io.File;
> import java.io.FileInputStream;
> import java.util.List;
> import static java.util.Arrays.asList;
> public class StreamCachingTest extends CamelTestSupport {
>     public static final String URI_END_OF_ROUTE = "mock:end_of_route";
>     @EndpointInject(uri = URI_END_OF_ROUTE)
>     private MockEndpoint endOfRoute;
>     @Override
>     protected RouteBuilder createRouteBuilder() throws Exception {
>         return new RouteBuilder() {
>             @Override
>             public void configure() throws Exception {
>                 context.getTypeConverterRegistry().addFallbackTypeConverter(springTypeConverter(context, new ConversionService[]{new DefaultConversionService()}), true);
>                 from("direct:foo")
>                     .streamCaching()
>                     .bean(MyBean.class)
>                     .to(URI_END_OF_ROUTE);
>             }
>         };
>     }
>     @Test
>     public void stream_caching_with_spring() throws Exception {
>         endOfRoute.expectedMessageCount(1);
>         template.sendBody("direct:foo", new FileInputStream(new File("src/main/resources/banner.txt")));
>         endOfRoute.assertIsSatisfied();
>     }
>     public static class MyBean {
>         public List<Integer> someNumbers() {
>             return asList(1, 2, 3);
>         }
>     }
>     /**
>      * Copied from org.apache.camel.spring.boot.TypeConversionConfiguration (they are package protected)
>      **/
>     @Bean
>     SpringTypeConverter springTypeConverter(CamelContext camelContext, ConversionService[] conversionServices) {
>         SpringTypeConverter springTypeConverter = new SpringTypeConverter(asList(conversionServices));
>         camelContext.getTypeConverterRegistry().addFallbackTypeConverter(springTypeConverter, true);
>         return springTypeConverter;
>     }
>     @ConditionalOnMissingBean
>     @Bean
>     ConversionService defaultCamelConversionService(ApplicationContext applicationContext) {
>         DefaultConversionService service = new DefaultConversionService();
>         for (Converter converter : applicationContext.getBeansOfType(Converter.class).values()) {
>             service.addConverter(converter);
>         }
>         return service;
>     }
> }
> {code}
> Result:
> {code:none}
> org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[ID-CAW811-53239-1457446127171-0-2][Message: 1,2,3]
> 	at org.apache.camel.util.ObjectHelper.wrapCamelExecutionException(ObjectHelper.java:1658)
> 	at org.apache.camel.util.ExchangeHelper.extractResultBody(ExchangeHelper.java:646)
> 	at org.apache.camel.impl.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:471)
> 	at org.apache.camel.impl.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:467)
> 	at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:139)
> 	at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:144)
> 	at no.avinor.agressointegration.StreamCachingTest.stream_caching_with_spring(StreamCachingTest.java:50)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
> 	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
> 	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
> 	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
> 	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
> 	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
> 	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
> 	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
> 	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
> 	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
> 	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
> 	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
> 	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
> 	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
> 	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
> 	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
> 	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
> 	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
> 	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
> 	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
> 	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
> 	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
> 	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> 	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
> Caused by: org.apache.camel.TypeConversionException: Error during type conversion from type: java.lang.String to the required type: org.apache.camel.StreamCache with value 1,2,3 due Failed to convert from type [java.util.Arrays$ArrayList<?>] to type [org.apache.camel.StreamCache] for value '[1, 2, 3]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.util.Arrays$ArrayList<?>] to type [org.apache.camel.StreamCache]
> 	at org.apache.camel.impl.converter.BaseTypeConverterRegistry.createTypeConversionException(BaseTypeConverterRegistry.java:610)
> 	at org.apache.camel.impl.converter.BaseTypeConverterRegistry.convertTo(BaseTypeConverterRegistry.java:137)
> 	at org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:72)
> 	at org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:47)
> 	at org.apache.camel.impl.DefaultStreamCachingStrategy.cache(DefaultStreamCachingStrategy.java:189)
> 	at org.apache.camel.processor.CamelInternalProcessor$StreamCachingAdvice.before(CamelInternalProcessor.java:765)
> 	at org.apache.camel.processor.CamelInternalProcessor$StreamCachingAdvice.before(CamelInternalProcessor.java:744)
> 	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:138)
> 	at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
> 	at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
> 	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
> 	at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
> 	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
> 	at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)
> 	at org.apache.camel.processor.UnitOfWorkProducer.process(UnitOfWorkProducer.java:68)
> 	at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:412)
> 	at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:380)
> 	at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:270)
> 	at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:380)
> 	at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:221)
> 	at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:124)
> 	at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:137)
> 	... 34 more
> Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.util.Arrays$ArrayList<?>] to type [org.apache.camel.StreamCache] for value '[1, 2, 3]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.util.Arrays$ArrayList<?>] to type [org.apache.camel.StreamCache]
> 	at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
> 	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
> 	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:176)
> 	at org.apache.camel.spring.boot.SpringTypeConverter.convertTo(SpringTypeConverter.java:40)
> 	at org.apache.camel.impl.converter.BaseTypeConverterRegistry.doConvertTo(BaseTypeConverterRegistry.java:333)
> 	at org.apache.camel.impl.converter.BaseTypeConverterRegistry.convertTo(BaseTypeConverterRegistry.java:120)
> 	... 54 more
> Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.util.Arrays$ArrayList<?>] to type [org.apache.camel.StreamCache]
> 	at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:313)
> 	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195)
> 	at org.springframework.core.convert.support.CollectionToObjectConverter.convert(CollectionToObjectConverter.java:64)
> 	at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:35)
> 	... 59 more
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)