6

I want to reload velocity template as it's changed. For this I've set the followings, but reload doesn't work when I manually change a .vm file inside META-INF/template/ .

velocimacro.library.autoreload = true
[spring|file|class].resource.loader.cache = false

Any idea? Here is my velocityEngine bean

<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
    <property name="resourceLoaderPath" value="classpath:META-INF/template/" />
    <property name="preferFileSystemAccess" value="false" />
    <property name="velocityProperties">
        <props>
            <prop key="spring.resource.loader.cache">false</prop>
            <prop key="file.resource.loader.cache">false</prop>
            <prop key="class.resource.loader.cache">false</prop>
            <prop key="velocimacro.library.autoreload">true</prop>

            <prop key="resource.loader">spring</prop>
            <prop key="directive.foreach.counter.name">counter</prop>
            <prop key="directive.foreach.counter.initial.value">0</prop>
            <prop key="spring.resource.loader.class">
                org.springframework.ui.velocity.SpringResourceLoader
            </prop>
        </props>
    </property>
</bean>
Mohsen
  • 3,512
  • 3
  • 38
  • 66

4 Answers4

7

As setResourceLoaderPath doc says:

Note that resource caching will be enabled in any case. With the file resource loader, the last-modified timestamp will be checked on access to detect changes. With SpringResourceLoader, the resource will be cached forever (for example for class path resources).

...

To enforce the use of SpringResourceLoader, i.e. to not resolve a path as file system resource in any case, turn off the "preferFileSystemAccess" flag. See the latter's javadoc for details.

Then for setPreferFileSystemAccess

Set whether to prefer file system access for template loading. File system access enables hot detection of template changes.

If this is enabled, VelocityEngineFactory will try to resolve the specified "resourceLoaderPath" as file system resource (which will work for expanded class path resources and ServletContext resources too).

Default is "true". Turn this off to always load via SpringResourceLoader (i.e. as stream, without hot detection of template changes), which might be necessary if some of your templates reside in an expanded classes directory while others reside in jar files.

So looks like there are a few things that contribute to the problem. Using SpringResourceLoader with classpath: pseudo-protocol makes Spring cache the template infinitely. On top of that preferFileSystemAccess is disabled which makes sure that template is never accessed through the file system.

Community
  • 1
  • 1
serg
  • 109,619
  • 77
  • 317
  • 330
  • 1
    Yes, it seems that SpringResourceLoader always caches. I was only able to turn off caching by using another resource loader such as org.apache.velocity.runtime.resource.loader.FileResourceLoader. Thanks. – Mohsen Sep 05 '11 at 06:36
2

Adding this property resolved this issue for me:

velocimacro.permissions.allow.inline.to.replace.global=true

I had the same problem when using the properties below but adding the above property enabled me to get auto-reload to work:

velocimacro.library.autoreload=true
file.resource.loader.cache=false

Please see How to edit a velocimacro without restarting velocity?

Community
  • 1
  • 1
Edd
  • 8,402
  • 14
  • 47
  • 73
1

Ok, i have velocityEngine bean set like this:

<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/templates/"/>
        <property name="velocityProperties">
            <props>
                <prop key="input.encoding">utf-8</prop>
             </props>
        </property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
        <property name="cache" value="false"/>
        <property name="prefix" value=""/>
        <property name="suffix" value=".xhtml"/>
        <property name="contentType" value="text/html; charset=UTF-8" />
        <property name="exposeSpringMacroHelpers" value="true"/>
</bean>

(Assuming you use Spring framework, by the way) and I have no problems with caching whatsoever. But I use the configurer bean instead of beanfactory. Try look into this.

And there's the thing, it's trivial, but still..., do you actually redeploy your project after modifying the template?

Tomáš Plešek
  • 1,482
  • 2
  • 12
  • 21
  • I don't use velocity as view generator. This is just used as template engine to some text content generation. Yes, as I checked the file is automatically redeployed to tomcat and should be visible to the application server. – Mohsen Sep 04 '11 at 15:02
0

I had the same issue in the past, so I've written this blog entry: Spring-mvc + Velocity + DCEVM

The principal idea is to use this at least at development time:

webapp.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader
webapp.resource.loader.path = /WEB-INF/views/
webapp.resource.loader.cache = true
webapp.resource.loader.modificationCheckInterval = 2

I've found that it works better than the SpringResourceLoader because now in my templates I can have includes like these:

#parse("/parts/header.vm")

Where the path of the header is in /WEB-INF/views/header.vm

reevesy
  • 3,452
  • 1
  • 26
  • 23
Rafael Sanches
  • 1,823
  • 21
  • 28