You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Camel 4.4升级至4.8后,含Rest与Direct路由的RouteBuilder异常

Apache Camel 4.4升级至4.8后Rest与Direct路由共存时Direct路由未注册问题

问题现象

将Apache Camel从4.4版本升级到4.8版本后,出现以下异常行为:

  • 同一个RouteBuilder中同时定义Rest路由和Direct路由时,仅Rest路由被注册并启动,Direct路由未被注册
  • 移除Rest路由后,Direct路由可正常注册启动
  • 将Direct路由替换为Seda路由时,所有路由均能正常注册

复现测试代码

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertNotNull;

public class CamelRouteTest extends CamelTestSupport {
    @Test
    public void testContext() throws Exception {
        context.addRoutes(new TestRouteBuilder());
        context.start();
        assertNotNull(context.hasEndpoint("direct:hello"));
        assertNotNull(context.hasEndpoint("direct:bye"));
    }

    private static class TestRouteBuilder extends RouteBuilder {

        @Override
        public void configure() {
            rest("/say")
                    .get("/hello").to("direct:hello")
                    .get("/bye").consumes("application/json").to("direct:bye")
                    .post("/bye").to("mock:update");

            from("direct:hello")
                    .transform().constant("Hello World");

            from("direct:bye")
                    .transform().constant("Bye World");
        }
    }
}

原因分析

这是Apache Camel 4.6及以后版本的行为变更:当Rest DSL中引用Direct端点时,Camel对Direct端点的生命周期管理做了优化。默认情况下,若Direct端点仅被Rest路由作为生产者引用,且对应的消费者路由在同一个RouteBuilder中,会出现消费者路由未被正确注册的情况。而Seda路由不受此影响,因为Seda的端点生命周期管理逻辑与Direct不同。

解决方案

提供两种可行的解决方法:

方法一:拆分路由到不同的RouteBuilder

将Rest路由和Direct路由分别放在独立的RouteBuilder中,再依次添加到Camel上下文:

// Rest路由单独的RouteBuilder
private static class RestRouteBuilder extends RouteBuilder {
    @Override
    public void configure() {
        rest("/say")
                .get("/hello").to("direct:hello")
                .get("/bye").consumes("application/json").to("direct:bye")
                .post("/bye").to("mock:update");
    }
}

// Direct路由单独的RouteBuilder
private static class DirectRouteBuilder extends RouteBuilder {
    @Override
    public void configure() {
        from("direct:hello")
                .transform().constant("Hello World");

        from("direct:bye")
                .transform().constant("Bye World");
    }
}

// 测试方法中添加两个路由
@Test
public void testContext() throws Exception {
    context.addRoutes(new RestRouteBuilder());
    context.addRoutes(new DirectRouteBuilder());
    context.start();
    assertNotNull(context.hasEndpoint("direct:hello"));
    assertNotNull(context.hasEndpoint("direct:bye"));
}

方法二:显式设置Direct路由的自动启动属性

在Direct路由上显式添加autoStartup(true)配置,确保路由被强制注册启动:

from("direct:hello")
        .autoStartup(true)
        .transform().constant("Hello World");

from("direct:bye")
        .autoStartup(true)
        .transform().constant("Bye World");

验证说明

采用上述任意一种方法后,重新运行测试,direct:hello和direct:bye端点将被正常注册,测试断言通过。

内容的提问来源于stack exchange,提问作者Bob Wernsman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:08:11