【问题标题】:Apache Camel java.lang.ClassCastException when building route dynamically from Spring XML configuration components从 Spring XML 配置组件动态构建路由时的 Apache Camel java.lang.ClassCastException
【发布时间】:2016-12-01 20:53:50
【问题描述】:

我们根据存储在数据库中的配置参数动态构建骆驼路线。我们有构建所有骆驼路线的通用类。一些参数刚刚以原始 Camel Spring XML 的形式呈现。构建骆驼路线的类扩展了 RouteBuilder,这是构建骆驼路线的部分代码:

@Override
    public void configure() throws Exception {
        RouteDefinition route = from(inputFile);
        configureSpringXMLActivity(0, route, convertBodyXml);
        configureSpringXMLActivity(5, route, setHeaderXml);
    }

    void configureSpringXMLActivity(final Integer seq, final RouteDefinition route, final String xmlConfig)
            throws Exception {
        ActivityIdentifier identifier = new CamelActivityIdentifier(seq);
        route.process(new ActivityHandoverProcessor(identifier));
        final ChoiceDefinition choice = route.choice().when(new ActivityPredicate(identifier));

        RouteContext routeContext = new DefaultRouteContext(camelContext, route, route.getInputs().get(0),
                camelContext.getRoutes());

        final StringReader reader = new StringReader(xmlConfig);
        Object result = esb.getConfigUnmarshaller().unmarshal(reader);
        if (result != null) {
            ProcessorDefinition<?> processorDefinition = (ProcessorDefinition<?>) result;
            Processor processor = processorDefinition.createProcessor(routeContext);
            choice.process(processor);
        }

在哪里

/** setHeader xml. */
    private final String setHeaderXml = "<setHeader headerName=\"extractFileName\" xmlns=\"http://camel.apache.org/schema/spring\"><simple>${body}</simple></setHeader>";

    /** convertBody xml. */
    private final String convertBodyXml = "<convertBodyTo xmlns=\"http://camel.apache.org/schema/spring\" type=\"java.lang.String\"/>";

当我们启动骆驼上下文时,它会在创建 setHeader 处理器时产生异常。

java.lang.ClassCastException: org.apache.camel.model.ProcessDefinition cannot be cast to org.apache.camel.model.SetHeaderDefinition
    at org.apache.camel.management.DefaultManagementObjectStrategy.getManagedObjectForProcessor(DefaultManagementObjectStrategy.java:355)
    at org.apache.camel.management.DefaultManagementLifecycleStrategy.getManagedObjectForProcessor(DefaultManagementLifecycleStrategy.java:515)
    at org.apache.camel.management.DefaultManagementLifecycleStrategy.getManagedObjectForService(DefaultManagementLifecycleStrategy.java:467)
    at org.apache.camel.management.DefaultManagementLifecycleStrategy.onServiceAdd(DefaultManagementLifecycleStrategy.java:378)
    at org.apache.camel.impl.RouteService.startChildService(RouteService.java:338)
    at org.apache.camel.impl.RouteService.warmUp(RouteService.java:182)
    at org.apache.camel.impl.DefaultCamelContext.doWarmUpRoutes(DefaultCamelContext.java:3496)
    at org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:3426)
    at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:3203)
    at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3059)
    at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:175)
    at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2854)
    at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2850)
    at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:2873)
    at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:2850)
    at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
    at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:2819)

在 Camel(版本 2.17.0)源代码 - 类 DefaultManagementObjectStrategy:

..........
   } else if(target1 instanceof SetHeaderProcessor) {
                    answer = new ManagedSetHeader(context, (SetHeaderProcessor)target1, (SetHeaderDefinition)definition);
.........

强制转换 (SetHeaderDefinition) 定义失败

但是,我的第一个活动 - convertBodyXml 没有问题。在同一个 Camel 类中:

if(target1 instanceof ConvertBodyProcessor) {
                    answer = new ManagedConvertBody(context, (ConvertBodyProcessor)target1, definition);

在这种情况下,骆驼代码不需要强制转换定义来创建托管对象:...,定义)

DefaultManagementObjectStrategy 类在创建某些托管对象时会转换为特定定义,但不会在其他对象上进行转换。

能否请您推荐如何绕过 ClassCastException,但仍从通用 ProcessorDefinition 对象构建路由。

提前致谢。

【问题讨论】:

  • 对于您正在尝试做的事情来说,这似乎是一种非常复杂的方法。

标签: apache-camel classcastexception


【解决方案1】:

无需从ProcessorDefinition 构造Processor 并在ChoiceDefinition 上调用process 方法,而是可以直接在ChoiceDefinition 上使用ProcessorDefinition 参数调用addOutput 方法。

基本上,choice.addOutput(processorDefinition);

这里是更新的sn-p:

@Override
    public void configure() throws Exception {
        RouteDefinition route = from(inputFile);
        configureSpringXMLActivity(0, route, convertBodyXml);
        configureSpringXMLActivity(5, route, setHeaderXml);
    }

    void configureSpringXMLActivity(final Integer seq, final RouteDefinition route, final String xmlConfig)
            throws Exception {
        ActivityIdentifier identifier = new CamelActivityIdentifier(seq);
        route.process(new ActivityHandoverProcessor(identifier));
        final ChoiceDefinition choice = route.choice().when(new ActivityPredicate(identifier));


        final StringReader reader = new StringReader(xmlConfig);
        Object result = esb.getConfigUnmarshaller().unmarshal(reader);
        if (result != null) {
            ProcessorDefinition<?> processorDefinition = (ProcessorDefinition<?>) result;
            choice.addOutput(result);
        }

希望对大家有所帮助

【讨论】:

    猜你喜欢
    • 2019-05-06
    • 2018-07-01
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多