ResourceManager : unable to find resource 'emailTemplate.vm' in any resource loader
Solution 1
You are falling into a common pitfall when using velocity with spring : you place your templates in one location and use a resource loader that searches them in another place. So you have 2 common usages :
put templates in classpath (as you do) and use
ClasspathResourceLoader
resource.loader = class class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
it is simple with little dependencies, but it forces you to put templates in classpath ...
put templates under
WEB-INF
(as you would do for JSPs) and useWebappResourceLoader
from velocity toolsresource.loader=webapp webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader webapp.resource.loader.path=/WEB-INF/velocity/
it is more natural for a template location, but you add a dependency on velocity tools.
And let spring manage dependencies but not instanciating via new
...
Solution 2
I had the same problem recently with karaf OSGi framework. In a CXF resource class (Login in this context) you have to initialize the Velocity Engine like this:
public Login() {
/* first, get and initialize an engine */
ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
}
Then, in the web method, instantiate the template:
/* create a context and add data */
synchronized (initLock) {
if (loginTemplate == null) {
loginTemplate = ve.getTemplate("templates/login.vm");
}
}
VelocityContext context = new VelocityContext();
Unfortunately, it didn't work out to load the template immediately after the ve.init()
call in the constructor.
user3691501
Updated on July 09, 2022Comments
-
user3691501 almost 2 years
I am doing an application in springs with maven. i wrote all properties in app.properties file
file structure is like this
src/main/resource |_ | templates | |_mytempaltefile.vm |_ app.properties
i gave the path(absloute) in app.property
app.properties file
template.base.path=D\:/SVN/trunk/tfbdirect/src/main/resources/templates
utilities-spring.xml
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> <property name="velocityProperties"> <props> <prop key="resource.loader">file</prop> <prop key="file.resource.loader.class"> org.apache.velocity.runtime.resource.loader.FileResourceLoader </prop> <prop key="file.resource.loader.path">${template.base.path}</prop> <prop key="file.resource.loader.cache">false</prop> </props> </property> </bean>
my class
import java.util.HashMap; import java.util.Map; import org.apache.velocity.app.VelocityEngine; import org.springframework.ui.velocity.VelocityEngineUtils; import com.providerpay.tfbdirect.service.mail.MailSenderService; public class LoginServiceImpl implements ILoginService{ /** * Injected through Spring IOC */ ILoginDAO loginDAO; ClaimRuleProcessServiceImpl claimRuleProcessServiceImpl; PlatformTransactionManager txmanager; //IForgotPasswordDAO forgotPasswordDAO; private VelocityEngine velocityEngine; private String appURL; private MailSenderService mailSenderService; TFBLogger log = TFBLoggerFactory.getLogger(RuleServer.class); public String getAppURL() { return appURL; } public void setAppURL(String appURL) { this.appURL = appURL; } public MailSenderService getMailSenderService() { return mailSenderService; } public VelocityEngine getVelocityEngine() { return velocityEngine; } public void setVelocityEngine(VelocityEngine velocityEngine) { this.velocityEngine = velocityEngine; } public void setMailSenderService(MailSenderService mailSenderService) { this.mailSenderService = mailSenderService; } public ILoginDAO getLoginDAO() { return loginDAO; } public void setLoginDAO(ILoginDAO loginDAO) { this.loginDAO = loginDAO; } public ClaimRuleProcessServiceImpl getClaimRuleProcessServiceImpl() { return claimRuleProcessServiceImpl; } public void setClaimRuleProcessServiceImpl( ClaimRuleProcessServiceImpl claimRuleProcessServiceImpl) { this.claimRuleProcessServiceImpl = claimRuleProcessServiceImpl; } public void setTxmanager(PlatformTransactionManager txmanager) { this.txmanager = txmanager; } /** * Validates Login * @param loginView * @return */ public boolean isValidLogin(LoginView loginView) { /* create tx definition object */ DefaultTransactionDefinition paramTransactionDefinition = new DefaultTransactionDefinition(); TransactionStatus status = txmanager.getTransaction(paramTransactionDefinition ); boolean result = false; try{ LoginEntity loginEntity = BeanMapper.INSTANCE.viewToEntityMapper(loginView); Feedback feedback = claimRuleProcessServiceImpl.validateClaimEligibility(loginEntity); log.info( "Rule executed was " +feedback.getAll()); for (FeedbackMessage feedbackmessaage :feedback.getAll()) { log.info("\n--------------"); log.info(feedbackmessaage.getRuleCd()); log.info(feedbackmessaage.getMessage()); log.info(feedbackmessaage.getSeverity().getName()); log.info("\n--------------"); } result = loginDAO.isValidLogin(loginEntity); log.debug("result = {}", result); txmanager.commit(status); }catch(Exception e){ txmanager.rollback(status); throw new TfbException("Error occured while validating login credentials"); } return result; } @Autowired VelocityEngine velocityengine; public boolean mailResetLink(LoginView loginView) { String toEmailAddress; LoginEntity loginEntity = BeanMapper.INSTANCE.viewToEntityMapper(loginView); /* getting user Email from DAO*/ toEmailAddress = loginDAO.getEmailByUsername(loginEntity); if(toEmailAddress != null && toEmailAddress.trim().length() > 0) { Map<String, Object> model = new HashMap<String, Object>(); model.put("user", loginEntity); model.put("appURL", appURL); String body = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "emailTemplate.vm","UTF-8", model); mailSenderService.sendMail("from mail", toEmailAddress, "Password Reset Link",body); } else { return false; } return true; } public boolean resetPassword(LoginView loginView) { LoginEntity loginEntity = BeanMapper.INSTANCE.viewToEntityMapper(loginView); return loginDAO.resetPassword(loginEntity); } }
every thing fine but i need to change the absolute path to relative path.. i tried many ways.
i tried like following
template.base.path=/templates/
but still getting below error .
ResourceManager : unable to find resource 'emailTemplate.vm' in any resource loader.
can any one help me..
Thanks in advance
-
Serge Ballesta almost 10 yearsIf using spring, avoid instanciating by new beans that should be injected in other beans or which should receive other beans by spring IOC because it will not work ...
-
user3691501 almost 10 yearsHi serge i added the code what you told top of the method but i am getting the same error only @Autowired VelocityEngine velocityEngine;
-
Torsten N. about 8 yearsWhen using either option with Spring Boot, would you put these configurations into application.properties? I'm having trouble getting any class loader to work, doesn't seem to matter which folder I put my templates in.
-
ZhaoGang almost 4 yearshow to config that in a yaml config file?