【问题标题】:Apache Camel error Because of ref must be specified on: process?Apache Camel 错误因为必须在以下位置指定 ref:进程?
【发布时间】:2019-09-30 10:39:23
【问题描述】:

我要做的是阅读邮件收件箱并查找主题行包含“错误”一词的电子邮件。

如果它发现一封邮件的主题行中没有“ERROR”这个词,那么它必须进入 onException 过程。

它一直工作到某个时候,我认为它会尝试处理,然后我得到一个错误。

public class MailRouteBuilder extends RouteBuilder {

   @Autowired
   ExceptionMailProcessor exceptionMailProcessor;

   @Override
   public void configure() throws Exception {
      String mailRouteStr = "imap://host.......";

      List<String> tmpKeywords = new ArrayList<>();
      tmpKeywords.add("ERROR"):

      onException(MailRouteException.class, RuntimeException.class).log(LoggingLevel.ERROR, "EXCEPTION in MAIL")
                .process(exceptionMailProcessor)
                .end();

      from(mailRouteStr).routeId("mymail")
             .validate(header("subject").in(tmpKeywords))
             .log("Sending to Mail Queue")
             .to("{{jmsMailIn}}")
             .log("Done with Mail Queue")
             .end();
    }
.
.
.

我的 ExceptionMailProcessor 类。

@Component
public class ExceptionMailProcessor implements Processor {

    @Override
    public void process(Exchange exchange) throws Exception {

        String messageBody;
        Exception e = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);

    }
}

错误:

org.apache.camel.FailedToCreateRouteException: Failed to create route mymail at: >>> OnException[[class MailRouteException, class java.lang.RuntimeException] -> [Log[EXCEPTION in MAIL], process[Processor@0x0]]] <<< in route: Route(mymail)[[From[imap://mai... because of ref must be specified on: process[Processor@0x0]
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1352)
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:212)
    at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:1140)
    at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:3735)
    at org.apache.camel.impl.DefaultCamelContext.addRouteDefinitions(DefaultCamelContext.java:1072)
    at org.apache.camel.builder.RouteBuilder.populateRoutes(RouteBuilder.java:478)
    at org.apache.camel.builder.RouteBuilder.addRoutesToCamelContext(RouteBuilder.java:391)
    at org.apache.camel.impl.DefaultCamelContext$3.call(DefaultCamelContext.java:1024)
    at org.apache.camel.impl.DefaultCamelContext$3.call(DefaultCamelContext.java:1021)
    at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:3267)
    at org.apache.camel.impl.DefaultCamelContext.addRoutes(DefaultCamelContext.java:1021)
    at com.agile.net.international.mc360.routing.routebuilder.process.mail.MailRouteProcess.lambda$checkMailDataSourceRoutes$0(MailRouteProcess.java:135)
    at java.util.HashMap.forEach(HashMap.java:1289)
    at com.agile.net.international.mc360.routing.routebuilder.process.mail.MailRouteProcess.checkMailDataSourceRoutes(MailRouteProcess.java:131)
    at com.agile.net.international.mc360.routing.routebuilder.process.mail.MailRouteProcess.process(MailRouteProcess.java:60)
    at org.apache.camel.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:63)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
    at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:197)
    at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:79)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
Caused by: java.lang.IllegalArgumentException: ref must be specified on: process[Processor@0x0]
    at org.apache.camel.util.ObjectHelper.notNull(ObjectHelper.java:340)
    at org.apache.camel.model.ProcessDefinition.createProcessor(ProcessDefinition.java:99)
    at org.apache.camel.model.ProcessorDefinition.createProcessor(ProcessorDefinition.java:518)
    at org.apache.camel.model.ProcessorDefinition.createOutputsProcessorImpl(ProcessorDefinition.java:481)
    at org.apache.camel.model.ProcessorDefinition.createOutputsProcessor(ProcessorDefinition.java:448)
    at org.apache.camel.model.ProcessorDefinition.createOutputsProcessor(ProcessorDefinition.java:186)
    at org.apache.camel.model.OnExceptionDefinition.addRoutes(OnExceptionDefinition.java:210)
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1349)
    ... 22 more

错误中的 MailRouteProcess 类正是我构建 imap 字符串并将其添加到骆驼上下文的位置。

我想要的只是当路由失败时它会转到 ExceptionMailProcessor。在那里我会做一些事情,实际的邮件消息必须标记为已读并且不再处理。

【问题讨论】:

  • exceptionMailProcessor 为空,因此 Camel 尝试通过 ref 找到它 - 这也失败了。你需要找到原因,为什么exceptionMailProcessor 没有被注入到MailRouteBuilder 。也许您正在创建 MailRouteBuilder 作为实例而不是实际的 Spring bean?
  • 也许您正在创建 MailRouteBuilder 作为实例而不是实际的 Spring bean?我认为你是对的。我需要重新考虑我的设计。谢谢。
  • 所以只看这个例子中的答案:https://stackoverflow.com/questions/34311595/how-in-camel-to-add-and-start-routes-dynamically 可以有一个类来动态构建一个路由。但是那么如何添加 onException.process 处理程序呢?因为那是我失败的地方。

标签: exception apache-camel


【解决方案1】:

与其尝试在 ExceptionMailProcessor 的实例中自动装配,不如尝试将其作为 DSL 中的 bean 引用。通常对于我在 Camel 中的处理器,我使用 Spring Configuration 类将处理器注册为 bean,然后在 DSL 中引用它们:

@Configuration
public class AppConfig {

  @Bean(name = "ExceptionMailProcessor ")
  public ExceptionMailProcessor exceptionMailProcessor() {
    return new ExceptionMailProcessor();
  }
}

然后在您的 Camel DSL 中,您可以像这样引用它:

onException(MailRouteException.class, RuntimeException.class).log(LoggingLevel.ERROR, "EXCEPTION in MAIL")
                .to("bean:ExceptionMailProcessor")
                .end();

【讨论】:

    【解决方案2】:

    对我有用且需要更少代码的是使用构造函数注入(它也是更好的做法):

    public class MailRouteBuilder extends RouteBuilder {
    
       
       private final ExceptionMailProcessor exceptionMailProcessor;
    
       public MailRouteBuilder(ExceptionMailProcessor exceptionMailProcessor){
           this.exceptionMailProcessor = exceptionMailProcessor;
       } 
    
       @Override
       public void configure() throws Exception {
          String mailRouteStr = "imap://host.......";
    
          List<String> tmpKeywords = new ArrayList<>();
          tmpKeywords.add("ERROR"):
    
          onException(MailRouteException.class, RuntimeException.class).log(LoggingLevel.ERROR, "EXCEPTION in MAIL")
                    .process(exceptionMailProcessor)
                    .end();
    
          from(mailRouteStr).routeId("mymail")
                 .validate(header("subject").in(tmpKeywords))
                 .log("Sending to Mail Queue")
                 .to("{{jmsMailIn}}")
                 .log("Done with Mail Queue")
                 .end();
        }
     ...
    }
    

    Spring 将在此处暗示 Autowire(无需添加)。因此,如果您使用 Lombok,您可以省略 ctor 并在课堂上添加 @RequiredArgsConstructor。这将为每个 final 字段添加一个 ctor(对于所有注入的东西来说这是一个好的做法)。

    实际上我来到这里是因为我偶然发现了这个错误,因为我忘记在处理器字段中添加“final”,因此 Lombok 没有将它添加到 ctor。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 1970-01-01
      • 1970-01-01
      • 2022-06-23
      • 1970-01-01
      • 2015-06-22
      相关资源
      最近更新 更多