Java 驼峰recipientList太长,导致StackOverflow错误
在后续步骤中向这些文件写入数据之前,我正在使用收件人列表初始化30多个带有标题的文件。(编辑)我将一个文件按给定字段拆分为大约30个文件,这些新文件需要与原始文件相同的头。标题和按类型拆分是将使用文件的应用程序的要求 如果一个字符串中包含超过30个逗号分隔的完整文件路径,则当camel尝试解析该字符串时,会导致StackOverflow错误。我通过增加堆栈大小(目前)解决了这个问题 但必须有一个更健壮的解决方案,也许我可以使用相对文件路径 (编辑)代码: 然后,在SplitFileByProductType中:Java 驼峰recipientList太长,导致StackOverflow错误,java,apache-camel,stack-overflow,Java,Apache Camel,Stack Overflow,在后续步骤中向这些文件写入数据之前,我正在使用收件人列表初始化30多个带有标题的文件。(编辑)我将一个文件按给定字段拆分为大约30个文件,这些新文件需要与原始文件相同的头。标题和按类型拆分是将使用文件的应用程序的要求 如果一个字符串中包含超过30个逗号分隔的完整文件路径,则当camel尝试解析该字符串时,会导致StackOverflow错误。我通过增加堆栈大小(目前)解决了这个问题 但必须有一个更健壮的解决方案,也许我可以使用相对文件路径 (编辑)代码: 然后,在SplitFileByProdu
public void processLine(Exchange exchange) throws EmptyLineException {
String line = exchange.getIn().getBody(String.class);
String originalFileName = (String) exchange.getIn().getHeader(ORIGINAL_FILENAME_HEADER);
// various checks and errorhandling omitted for clariry
setoutputFileExchangeHeader(exchange, values[index].trim(), originalFileName, leftOversFileName);
exchange.getIn().setBody(line + fileFormat.getLineEnd());
}
实际工作在这里完成:
private void setoutputFileExchangeHeader(Exchange exchange, String product, String originalFileName, String leftOversFileName) {
if (isProductType(product)) {
// a regular line, write to appropriate file
exchange.getIn().setHeader(WRITE_FILENAME_HEADER,
fileNameFormatter.getProductFileDestination(originalFileName, product));
} else if (PRODUCT_COLUMN_NAME.equals(product)) {
// this is the header line, write the header to all files
exchange.getIn().setHeader(WRITE_FILENAME_HEADER, getAllFileNames(originalFileName, leftOversFileName));
} else {
// product not regognized, line goes to 'rest'
exchange.getIn().setHeader(WRITE_FILENAME_HEADER, leftOversFileName);
}
}
你说得对。我能够使用实际的ApacheCamel 2.21.1通过以下测试重现它<代码>接收者列表使用逗号分隔的端点列表在
堆栈溢出错误
上失败。但是,如果通过端点的列表
,则路线将按预期工作。因此,您可以修改SplitFileByProductType
处理器以创建端点列表,而不是逗号分隔的字符串
公共类LongRecipientListCausesStackOverflow扩展了CamelTestSupport{
私有静态最终整数计数=300;
私有静态最终字符串BASE_DIR=“D://temp/cameltest/”;
@凌驾
受保护的RouteBuilder createRouteBuilder()引发异常{
返回新的RouteBuilder(){
@凌驾
public void configure()引发异常{
from(“直接:in”)
.收件人列表(标题(“收件人”))
。至(“模拟:完成”);
}
};
}
@以前
public void clenup()引发异常{
deleteDirectory(新文件(BASE_DIR));
}
@试验
public void fails()引发异常{//fails,引发标头为字符串类型(“to”)的StackOverflower错误
MockEndpoint MockEndpoint=getMockEndpoint(“mock:done”);
String recipientListString=IntStream.range(0,COUNT).mapToObj(subDir->”文件:“+BASE_DIR+subDir).collect(Collectors.joining(“,”);
template.sendboyandheader(“direct:in”、“”、“to”、recipientListString);
mockEndpoint.assertessatified();
Assert.assertEquals(计数,新文件(BASE_DIR).listFiles().length);
}
@试验
public void passs()引发类型为List的头为(“to”)的异常{//pass
MockEndpoint MockEndpoint=getMockEndpoint(“mock:done”);
List recipientListList=IntStream.range(0,COUNT).mapToObj(subDir->“文件:+BASE_DIR+subDir).collect(Collectors.toList());
template.sendboyandheader(“直接:在“,”中,“收件人”,收件人列表);
mockEndpoint.assertessatified();
Assert.assertEquals(计数,新文件(BASE_DIR).listFiles().length);
}
}
也许会展示更多你正在做的代码,并告诉更多关于30多个文件的用例,这似乎有点不寻常。听起来不像是recipientList的理想用例。。。例如,您是否考虑将文件名放在列表中并使用拆分器?@ Viji-Stuvi,在路由的其余部分之前,在初始化之前,如何从UTIL.LIST启动路由?谢谢!这就成功了。我从来没有想到setHeader接受一个对象,而不一定是字符串。@Bedla,to
API在我的情况下在recipientList
之后不可用。我正在使用带弹簧靴的camel-http4。有什么问题吗?
private void setoutputFileExchangeHeader(Exchange exchange, String product, String originalFileName, String leftOversFileName) {
if (isProductType(product)) {
// a regular line, write to appropriate file
exchange.getIn().setHeader(WRITE_FILENAME_HEADER,
fileNameFormatter.getProductFileDestination(originalFileName, product));
} else if (PRODUCT_COLUMN_NAME.equals(product)) {
// this is the header line, write the header to all files
exchange.getIn().setHeader(WRITE_FILENAME_HEADER, getAllFileNames(originalFileName, leftOversFileName));
} else {
// product not regognized, line goes to 'rest'
exchange.getIn().setHeader(WRITE_FILENAME_HEADER, leftOversFileName);
}
}
public class LongRecipientListCausesStackOverflow extends CamelTestSupport {
private static final int COUNT = 300;
private static final String BASE_DIR = "D://temp/cameltest/";
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:in")
.recipientList(header("to"))
.to("mock:done");
}
};
}
@Before
public void clenup() throws Exception{
FileUtils.deleteDirectory(new File(BASE_DIR));
}
@Test
public void fails() throws Exception { //fails, throws StackOverflowError with header("to") of type String
MockEndpoint mockEndpoint = getMockEndpoint("mock:done");
String recipientListString = IntStream.range(0,COUNT).mapToObj(subDir -> "file:"+BASE_DIR+subDir).collect(Collectors.joining(","));
template.sendBodyAndHeader("direct:in","", "to", recipientListString);
mockEndpoint.assertIsSatisfied();
Assert.assertEquals(COUNT, new File(BASE_DIR).listFiles().length);
}
@Test
public void passes() throws Exception { //pass with header("to") of type List<String>
MockEndpoint mockEndpoint = getMockEndpoint("mock:done");
List<String> recipientListList = IntStream.range(0,COUNT).mapToObj(subDir -> "file:"+BASE_DIR+subDir).collect(Collectors.toList());
template.sendBodyAndHeader("direct:in","", "to", recipientListList);
mockEndpoint.assertIsSatisfied();
Assert.assertEquals(COUNT, new File(BASE_DIR).listFiles().length);
}
}