Apache Camel <pollEnrich>标签致timer uri在XML上下文失效问题
问题描述
loadEmails定时器原本每5秒精准触发一次,emailConfigProcessor也会每5秒从自动注入的emailConfigBean获取配置并加载。但启用<pollEnrich>标签后,定时器无法周期性触发——通过注释/取消注释该标签已验证此现象:注释后定时器和emailConfigProcessor的日志均能正常周期性打印。
camel-context.xml
<route id="mail-route-imap" autoStartup="true"> <!-- Input to trigger the route --> <from uri="timer://loadEmails?period=5000&fixedRate=false" /> <log message="Timer triggered!" /> <!-- Log when the timer triggers --> <log message="Timer triggered, calling emailConfigProcessor..." /> <process ref="emailConfigProcessor" /> <log message="IMAP URL: ${exchangeProperty.imapUrl}, IMAP Port: ${exchangeProperty.imapPort}" /> <!-- Poll from IMAP dynamically using pollEnrich --> <pollEnrich timeout="10000000"> <simple>imaps://${exchangeProperty.imapUrl}:${exchangeProperty.imapPort}?authenticator=#exchangeAuthenticator&debugMode=true&delete=false&unseen=true&delay=10000&mail.imaps.proxy.host={{proxyHost}}&mail.imaps.proxy.port={{proxyPort}}&mail.imaps.auth.mechanisms=XOAUTH2&searchTerm=#customSearchTerm</simple> </pollEnrich> <log message="Route 'mail-route-imap' registered successfully." /> </route>
EmailConfigProcessor.java
public class EmailConfigProcessor implements Processor { @Autowired private EmailConfigBean emailConfigBean; @Override public void process(Exchange exchange) throws Exception { LOG.info("@#E#@@# EmailConfigProcessor ..... {} ", new Date()); exchange.setProperty("imapUrl", emailConfigBean.getImapUrl()); //this is fetched clean and logged exchange.setProperty("imapPort", emailConfigBean.getImapPort()); //this is fetched clean and logged } }
更新内容
将pollEnrich超时改为10秒、定时器周期改为1秒后,邮件配置可正常获取,但每次邮件链回复都会抛出FolderClosedException错误:
org.apache.camel.spi.CamelLogger: Error occurred: Error during type conversion from type: javax.mail.internet.MimeMultipart to the required type: org.apache.camel.StreamCache with value javax.mail.internet.MimeMultipart@49f542c2 due to org.apache.camel.TypeConversionException: Error during type conversion from type: javax.mail.internet.MimeMultipart to the required type: org.apache.camel.StreamCache with value javax.mail.internet.MimeMultipart@49f542c2 due to javax.mail.FolderClosedException: null
解决方案
1. 定时器阻塞问题
定时器无法周期性触发的核心原因是Camel路由默认单线程串行执行,而你设置的pollEnrich超时时间长达约2.7小时(10000000毫秒),前一次路由一直在等待pollEnrich超时,导致后续定时器任务被阻塞。
解决办法二选一:
- 大幅降低
pollEnrich的超时时间,比如设置为10秒(10000毫秒),避免长时间占用路由线程 - 给
pollEnrich配置独立线程池,让它在后台执行,不阻塞主路由的定时器循环:
同时在Spring上下文定义线程池:<pollEnrich timeout="10000" executorService="#myExecutorService"> <!-- 原IMAP URI配置 --> </pollEnrich><bean id="myExecutorService" class="java.util.concurrent.Executors" factory-method="newFixedThreadPool"> <constructor-arg value="5"/> </bean>
2. FolderClosedException问题
该错误是因为IMAP文件夹在邮件内容转换为StreamCache前就被关闭了,解决建议:
- 在IMAP URI中添加
closeFolder=false参数,禁止组件处理完邮件后立即关闭文件夹,直到路由完全处理完毕 - 在
pollEnrich后立即执行内容转换,提前缓存邮件内容:<pollEnrich timeout="10000"> <!-- 原IMAP URI配置 --> </pollEnrich> <convertBodyTo type="org.apache.camel.StreamCache"/> - 检查自定义
customSearchTerm的实现,确保没有提前关闭IMAP文件夹的逻辑 - 验证Camel邮件组件与JavaMail版本的兼容性,避免版本不匹配导致的资源管理异常
内容的提问来源于stack exchange,提问作者raikumardipak
相关产品推荐
相关产品推荐

