[jira] [Comment Edited] (CAMEL-10542) DataFormat from registry is used for every dataformat operation (marshal/unmarshal)
[ https://issues.apache.org/jira/browse/CAMEL-10542?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15713012#comment-15713012 ] Luca Burgazzoli edited comment on CAMEL-10542 at 12/2/16 7:58 AM: -- I was thinking about a real factory that can create an instance of a dataformat, like what you can achieve by annotate a method with prototype scope in spring and similar to what happen when we create an instance from a resource file except you can provide a data format with your own defaults. was (Author: lb): I was thinking about a real factory that can create an instance of a dataformat, like what you can achieve by annotate a method with prototype scope in spring > 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} > http://camel.apache.org/schema/spring";> > > > > > > > > > > > > > > {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)
[jira] [Comment Edited] (CAMEL-10542) DataFormat from registry is used for every dataformat operation (marshal/unmarshal)
[ 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} > http://camel.apache.org/schema/spring";> > > > > > > > > > > > > > > {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)