[ https://issues.apache.org/jira/browse/CAMEL-10542?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15707999#comment-15707999 ]
Luca Burgazzoli edited comment on CAMEL-10542 at 11/30/16 9:03 AM: ------------------------------------------------------------------- Yes you don't as in such case the dataformat instance is created using "service-loader" style thus a new instance is created each time DefaultDataFormatResolver::resolveDataFormat is invoked. I have experimentedd with @Scope("prototype") and it solves the issue for Spring Boot, but I do not know what could be optimal solution that would cover all the cases and containers. was (Author: lb): Yes you don't as in such case the dataformat instance is created using "service-loader" style thus a new instance is created each time DefaultDataFormatResolver::resolveDataFormat is invoked. > DataFormat from registry is used for every dataformat operation > (marshal/unmarshal) > ----------------------------------------------------------------------------------- > > Key: CAMEL-10542 > URL: https://issues.apache.org/jira/browse/CAMEL-10542 > Project: Camel > Issue Type: Bug > Components: camel-core > Reporter: Luca Burgazzoli > Assignee: Luca Burgazzoli > Fix For: 2.18.2, 2.19.0 > > > While working on an issue related to spring-boot I found out that if a data > format is registered in camel registry with the same name as the one camel > looks-up with the help of DefaultDataFormatResolver, this object is then > re-configured for each data format definition so one definition may override > previous configuration with an undefined behavior. > So assume you have an xml route definitions as: > {code:xml} > <routes xmlns="http://camel.apache.org/schema/spring"> > <route> > <from uri="direct:unmarshal"/> > <unmarshal> > <csv delimiter=";" headerDisabled="true"/> > </unmarshal> > </route> > <route> > <from uri="direct:marshal"/> > <marshal> > <csv headerDisabled="true" quoteDisabled="true"/> > </marshal> > </route> > </routes> > {code} > And some code like: > {code:java} > InputStream is = getClass().getResourceAsStream("..."); > SimpleRegistry reg = new SimpleRegistry(); > reg.put("csv-dataformat", new CsvDataFormat()); > DefaultCamelContext ctx = new DefaultCamelContext(reg); > ctx.addRouteDefinitions(ctx.loadRoutesDefinition(is).getRoutes()); > ctx.start(); > ProducerTemplate template = ctx.createProducerTemplate(); > String result = template.requestBody( > "direct:marshal", > Arrays.asList(Arrays.asList( "A1", "B1", "C1" )), > String.class); > assertEquals("A1,B1,C1", result); > ctx.stop > {code} > Then this test fails with: > {code} > Expected :A1,B1,C1 > Actual :A1;B1;C1 > {code} > It fails because the object added to the SimpleRegistry is shared among the > two csv dataformats so it is configured to have delimiter = ';' > For spring-boot this causes some issues as it registers data formats beans as > part of its auto-configuration magic thus if you do not set your own instance > of data format, any data format operation like marshal/unmarshal may not work > as expected. > - for spring-boot a solution would be to annotate auto configured data format > beans with prototype scope. > - a more generic solution would be to make DataFormat Cloneable and clone the > bean found in the registry -- This message was sent by Atlassian JIRA (v6.3.4#6332)