Java 驼峰recipientList太长,导致StackOverflow错误

Java 驼峰recipientList太长,导致StackOverflow错误,java,apache-camel,stack-overflow,Java,Apache Camel,Stack Overflow,在后续步骤中向这些文件写入数据之前,我正在使用收件人列表初始化30多个带有标题的文件。(编辑)我将一个文件按给定字段拆分为大约30个文件,这些新文件需要与原始文件相同的头。标题和按类型拆分是将使用文件的应用程序的要求 如果一个字符串中包含超过30个逗号分隔的完整文件路径,则当camel尝试解析该字符串时,会导致StackOverflow错误。我通过增加堆栈大小(目前)解决了这个问题 但必须有一个更健壮的解决方案,也许我可以使用相对文件路径 (编辑)代码: 然后,在SplitFileByProdu

在后续步骤中向这些文件写入数据之前,我正在使用收件人列表初始化30多个带有标题的文件。(编辑)我将一个文件按给定字段拆分为大约30个文件,这些新文件需要与原始文件相同的头。标题和按类型拆分是将使用文件的应用程序的要求

如果一个字符串中包含超过30个逗号分隔的完整文件路径,则当camel尝试解析该字符串时,会导致StackOverflow错误。我通过增加堆栈大小(目前)解决了这个问题

但必须有一个更健壮的解决方案,也许我可以使用相对文件路径

编辑)代码:

然后,在SplitFileByProductType中:

   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);
    }
}