Velocity资源找不到问题求助:配置正常但模板文件无法定位
问题描述
遇到org.apache.velocity.exception.ResourceNotFoundException错误,提示无法找到资源en/newuserpassword.html。已通过notification.properties指定模板路径,调试可读取到路径值,但实际文件存放在resources/com/app/application/notification/template/en/newuserpassword.html却无法被定位。应用整体运行正常,同类审计消息配置能正常加载对应模板。
错误堆栈
org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'en/newuserpassword.html'
at org.apache.velocity.runtime.resource.ResourceManagerImpl.loadResource(ResourceManagerImpl.java:474)
at org.apache.velocity.runtime.resource.ResourceManagerImpl.getResource(ResourceManagerImpl.java:352)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533)
at org.apache.velocity.app.VelocityEngine.mergeTemplate(VelocityEngine.java:343)
at org.apache.velocity.app.VelocityEngine.mergeTemplate(VelocityEngine.java:320)
通知消息Spring配置
<bean id="notificationResolver" class="com..application.notification.resolver.VelocityNotificationResolver"> <constructor-arg> <bean class="com.amor.hcplus.application.util.spring.context.TypeConvertingReloadableResourceBundleMessageSource"> <property name="cacheSeconds" value="60" /> <property name="basenames"> <list> <value>classpath:com/app/application/notification/notifications</value> <value>WEB-INF/spring/i18n/enums</value> </list> </property> </bean> </constructor-arg> <constructor-arg> <bean id="velocityEngine" class="org.apache.velocity.app.VelocityEngine"> <constructor-arg ref="velocityProperties"/> </bean> </constructor-arg> </bean>
可正常工作的审计消息配置
<bean id="auditMessageResolver" class="com.amor.hcplus.application.audit.domain.VelocityAuditMessageResolver"> <constructor-arg> <bean class="com.application.util.spring.context.TypeConvertingReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>WEB-INF/spring/i18n/enums</value> <value>classpath:com/app/application/audit/auditing</value> </list> </property> </bean> </constructor-arg> <constructor-arg> <bean id="velocityEngine" class="org.apache.velocity.app.VelocityEngine"> <constructor-arg ref="velocityProperties"/> </bean> </constructor-arg> </bean>
排查与解决方向
- 核对Velocity资源加载配置:检查
velocityProperties中是否正确设置了资源加载器(如resource.loader=class)和模板根路径(class.resource.loader.path需指向com/app/application/notification/template,classpath路径无需加classpath:前缀),对比审计模块的配置差异。 - 验证模板路径拼接逻辑:确认代码调用
mergeTemplate时传入的相对路径en/newuserpassword.html,是否能基于VelocityEngine的根路径定位到实际文件。 - 检查编译后文件存在性:确认打包后
target/classes/com/app/application/notification/template/en/newuserpassword.html是否存在,排查IDE编译或打包过程中是否遗漏资源文件。 - 区分MessageSource与Velocity路径:注意
TypeConvertingReloadableResourceBundleMessageSource是加载国际化消息的配置,与Velocity模板路径是独立设置,不要混淆两者的路径配置。
内容的提问来源于stack exchange,提问作者dynamo

