Quantcast

Reloading resources adding new macros

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Reloading resources adding new macros

Greg Huber
The was one issue that has been around for ages, and I am not sure if it is
possible to fix it.

If I have added a new macro into a velocity template file loaded via a
resource loader, I have to shut down the container (tomcat) and restart for
it to be picked up.  I will allow the contents of the macro to be changed
but not a new macro.  I did try to see if I could fix it but without much
success.

my velocity.properties :
..
webapp.resource.loader.description=Webapp Resource Loader
webapp.resource.loader.class=rendering.velocity.WebappResourceLoader
webapp.resource.loader.cache=true
webapp.resource.loader.path=/WEB-INF/velocity,/WEB-INF/velocity/templates,/WEB-INF/velocity/templates/feeds,/WEB-INF/velocity/templates/emails
...

If you are now familiar with the code you might be in a better position to
see why I have to shut down for it to be picked up.

Cheers Greg
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reloading resources adding new macros

Christopher Schultz-2
Greg,

On 1/4/17 8:43 AM, Greg Huber wrote:

> The was one issue that has been around for ages, and I am not sure if it is
> possible to fix it.
>
> If I have added a new macro into a velocity template file loaded via a
> resource loader, I have to shut down the container (tomcat) and restart for
> it to be picked up.  I will allow the contents of the macro to be changed
> but not a new macro.  I did try to see if I could fix it but without much
> success.
>
> my velocity.properties :
> ..
> webapp.resource.loader.description=Webapp Resource Loader
> webapp.resource.loader.class=rendering.velocity.WebappResourceLoader
> webapp.resource.loader.cache=true
> webapp.resource.loader.path=/WEB-INF/velocity,/WEB-INF/velocity/templates,/WEB-INF/velocity/templates/feeds,/WEB-INF/velocity/templates/emails
> ...
>
> If you are now familiar with the code you might be in a better position to
> see why I have to shut down for it to be picked up.
Velocity version?

When you say you "shut down the container (tomcat)", can you be more
specific? Do you bounce the application, or do you terminate Tomcat and
the JVM, etc.?

Did you write your own WebappResourceLoader (and if so, why)?

-chris


signature.asc (924 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reloading resources adding new macros

Greg Huber
>Velocity version?

The latest version ie 2.0.

>When you say you "shut down the container (tomcat)", >can you be more
specific? Do you bounce the >application, or do you >terminate Tomcat and
the JVM, >etc.?

Terminate tomcat shutdown.sh and then restart it.

>Did you write your own WebappResourceLoader (and if >so, why)?

Its a bit application so I do have my own version.

I did read on a list that it was an issue.  Think Nathan
answered the post???

Maybe I have missed something in the code?


public class WebappResourceLoader extends ResourceLoader {

    private static Log log = LogFactory.getLog(WebappResourceLoader.class);

    // The root paths for templates (relative to webapp's root).
    protected String[] paths = null;
    protected HashMap<String, String> templatePaths = null;
    protected ServletContext servletContext = null;

    /**
     * This is abstract in the base class, so we need it. NOTE: this expects
     * that the ServletContext has already been placed in the runtime's
     * application attributes under its full class name (i.e.
     * "javax.servlet.ServletContext").
     *
     * @param configuration
     *            the configuration
     */
    @Override
    public void init(ExtProperties configuration) {

        if (log.isDebugEnabled())
            log.debug("WebappResourceLoader: initialization starting.");

        // get configured paths
        paths = configuration.getStringArray("path");
        if (paths == null || paths.length == 0) {
            paths = new String[1];
            paths[0] = "/";
        } else {
            // make sure the paths end with a "/"
            for (int i = 0; i < paths.length; i++) {
                if (!paths[i].endsWith("/")) {
                    paths[i] += "/";
                }
                if (log.isDebugEnabled())
                    log.debug("WebappResourceLoader: added template path -
'"
                            + paths[i] + "'");
            }
        }

        // Try out default
        servletContext = EventsContext.getServletContext();

        // get the ServletContext
        if (servletContext == null) {
            Object obj = rsvc
                    .getApplicationAttribute(ServletContext.class.getName()
);
            if (obj instanceof ServletContext) {
                servletContext = (ServletContext) obj;
            } else {
                log.error(
                        "WebappResourceLoader: unable to retrieve
ServletContext");
            }
        }

        if (log.isDebugEnabled()) {
            for (int i = 0; i < paths.length; i++) {
                log.debug("Servlet Context = "
                        + servletContext.getRealPath(paths[i]));
            }
        }

        // init the template paths map
        templatePaths = new HashMap<String, String>();

        if (log.isDebugEnabled())
            log.debug("WebappResourceLoader: initialization complete.");
    }

    /**
     * Get an InputStream so that the Runtime can build a template with it.
     *
     * @param name
     *            name of template to get
     * @param encoding
     *            the encoding
     *
     * @return InputStream containing the template
     *
     * @throws ResourceNotFoundException
     *             if template not found in classpath.
     */
    @Override
    public Reader getResourceReader(String name, String encoding)
            throws ResourceNotFoundException {

        // public synchronized InputStream getResourceStream(String name)
        // throws ResourceNotFoundException {

        InputStream result = null;

        Exception exception = null;

        if (name == null || name.length() == 0) {
            throw new ResourceNotFoundException(
                    "WebappResourceLoader: No template name provided");
        }

        // names are <template>:<deviceType>
        // loading events_macros.vm etc will not have the type so only
check for
        // one.
        String[] split = name.split(":", 2);
        if (split.length < 1) {
            throw new ResourceNotFoundException("Invalid ThemeRL key " +
name);
        }

        String savedPath = (String) templatePaths.get(name);
        if (savedPath != null) {

            result = servletContext.getResourceAsStream(savedPath +
split[0]);

        }

        if (result == null) {

            for (int i = 0; i < paths.length; i++) {

                String path = paths[i] + split[0];

                try {

                    result = servletContext.getResourceAsStream(path);

                    // save the path and exit the loop if we found the
template
                    if (result != null) {
                        templatePaths.put(name, paths[i]);
                        break;
                    }

                } catch (NullPointerException npe) {
                    // no servletContext was set, whine about it!
                    throw npe;
                } catch (Exception e) {
                    // only save the first one for later throwing
                    if (exception == null) {
                        if (log.isDebugEnabled()) {
                            log.debug("WebappResourceLoader: Could not load
"
                                    + path, e);
                        }
                        exception = e;
                    }
                }
            }
        }

        // If we never found the template
        if (result == null) {
            String msg = "WebappResourceLoader: Resource '" + name
                    + "' not found on class path.";

            // convert to a general Velocity ResourceNotFoundException
            if (exception == null) {
                throw new ResourceNotFoundException(msg);
            } else {
                msg += "  Due to: " + exception;
                throw new ResourceNotFoundException(msg, exception);
            }
        }

        return new BufferedReader(new InputStreamReader(result));
    }

    /**
     * Gets the cached file.
     *
     * @param rootPath
     *            the root path
     * @param fileName
     *            the file name
     *
     * @return the cached file
     */
    private File getCachedFile(String rootPath, String fileName) {

        // We do this when we cache a resource, so do it again to ensure a
match
        while (fileName.startsWith("/")) {
            fileName = fileName.substring(1);
        }

        String savedPath = (String) templatePaths.get(fileName);

        // names are <template>:<deviceType>
        // loading events_macros.vm etc will not have the type so only
check for
        // one.
        String[] split = fileName.split(":", 2);
        return new File(rootPath + savedPath, split[0]);

    }

    /**
     * Checks to see if a resource has been deleted, moved or modified. When
     * using the resource.loader.cache=true option
     *
     * @param resource
     *            Resource The resource to check for modification
     *
     * @return boolean True if the resource has been modified
     */
    public boolean isSourceModified(Resource resource) {

        String rootPath = servletContext.getRealPath("/");
        if (rootPath == null) {
            // RootPath is null if the servlet container cannot translate
the
            // virtual path to a real path for any reason (such as when the
            // content is being made available from a .war archive)
            return false;
        }

        // first, try getting the previously found file
        String fileName = resource.getName();
        File cachedFile = getCachedFile(rootPath, fileName);
        if (!cachedFile.exists()) {
            // then the source has been moved and/or deleted
            return true;
        }

        /*
         * Check to see if the file can now be found elsewhere before it is
         * found in the previously saved path
         */
        File currentFile = null;
        for (int i = 0; i < paths.length; i++) {
            currentFile = new File(rootPath + paths[i], fileName);
            if (currentFile.canRead()) {
                // stop at the first resource found (just like in
                // getResourceStream())
                break;
            }
        }

        // If the current is the cached and it is readable
        if (cachedFile.equals(currentFile) && cachedFile.canRead()) {
            // then (and only then) do we compare the last modified values
            return (cachedFile.lastModified() !=
resource.getLastModified());
        } else {
            // We found a new file for the resource or the resource is no
longer
            // readable.
            return true;
        }
    }

    /**
     * Checks to see when a resource was last modified
     *
     * @param resource
     *            Resource the resource to check
     *
     * @return long The time when the resource was last modified or 0 if the
     *         file can't be read
     */
    public long getLastModified(Resource resource) {

        String rootPath = servletContext.getRealPath("/");
        if (rootPath == null) {
            // RootPath is null if the servlet container cannot translate
the
            // virtual path to a real path for any reason (such as when the
            // content is being made available from a .war archive)
            return 0;
        }

        File cachedFile = getCachedFile(rootPath, resource.getName());
        if (cachedFile.canRead()) {
            return cachedFile.lastModified();
        } else {
            return 0;
        }

    }

}

On 4 January 2017 at 16:04, Christopher Schultz <
[hidden email]> wrote:

> Greg,
>
> On 1/4/17 8:43 AM, Greg Huber wrote:
> > The was one issue that has been around for ages, and I am not sure if it
> is
> > possible to fix it.
> >
> > If I have added a new macro into a velocity template file loaded via a
> > resource loader, I have to shut down the container (tomcat) and restart
> for
> > it to be picked up.  I will allow the contents of the macro to be changed
> > but not a new macro.  I did try to see if I could fix it but without much
> > success.
> >
> > my velocity.properties :
> > ..
> > webapp.resource.loader.description=Webapp Resource Loader
> > webapp.resource.loader.class=rendering.velocity.WebappResourceLoader
> > webapp.resource.loader.cache=true
> > webapp.resource.loader.path=/WEB-INF/velocity,/WEB-INF/
> velocity/templates,/WEB-INF/velocity/templates/feeds,/WEB-
> INF/velocity/templates/emails
> > ...
> >
> > If you are now familiar with the code you might be in a better position
> to
> > see why I have to shut down for it to be picked up.
>
> Velocity version?
>
> When you say you "shut down the container (tomcat)", can you be more
> specific? Do you bounce the application, or do you terminate Tomcat and
> the JVM, etc.?
>
> Did you write your own WebappResourceLoader (and if so, why)?
>
> -chris
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reloading resources adding new macros

Michael Osipov
In reply to this post by Greg Huber
Am 2017-01-04 um 14:43 schrieb Greg Huber:

> The was one issue that has been around for ages, and I am not sure if it is
> possible to fix it.
>
> If I have added a new macro into a velocity template file loaded via a
> resource loader, I have to shut down the container (tomcat) and restart for
> it to be picked up.  I will allow the contents of the macro to be changed
> but not a new macro.  I did try to see if I could fix it but without much
> success.
>
> my velocity.properties :
> ..
> webapp.resource.loader.description=Webapp Resource Loader
> webapp.resource.loader.class=rendering.velocity.WebappResourceLoader
> webapp.resource.loader.cache=true
> webapp.resource.loader.path=/WEB-INF/velocity,/WEB-INF/velocity/templates,/WEB-INF/velocity/templates/feeds,/WEB-INF/velocity/templates/emails
> ...
>
> If you are now familiar with the code you might be in a better position to
> see why I have to shut down for it to be picked up.

This could be your issue: http://stackoverflow.com/a/8656527/696632

Michael


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reloading resources adding new macros

Greg Huber
>This could be your issue: http://stackoverflow.com/a/8656527/696632

It picks up the changes to the contents of the template macros ok, so its
unlikely to be the tomcat cache.  It won't pick up the new macros.  I
though it might be a list/array that stores the names that needs to be
cleared/reset when the macro is reloaded, but it looked much more
complicated.

Cheers Greg

On 4 January 2017 at 17:34, Michael Osipov <[hidden email]> wrote:

> Am 2017-01-04 um 14:43 schrieb Greg Huber:
>
>> The was one issue that has been around for ages, and I am not sure if it
>> is
>> possible to fix it.
>>
>> If I have added a new macro into a velocity template file loaded via a
>> resource loader, I have to shut down the container (tomcat) and restart
>> for
>> it to be picked up.  I will allow the contents of the macro to be changed
>> but not a new macro.  I did try to see if I could fix it but without much
>> success.
>>
>> my velocity.properties :
>> ..
>> webapp.resource.loader.description=Webapp Resource Loader
>> webapp.resource.loader.class=rendering.velocity.WebappResourceLoader
>> webapp.resource.loader.cache=true
>> webapp.resource.loader.path=/WEB-INF/velocity,/WEB-INF/veloc
>> ity/templates,/WEB-INF/velocity/templates/feeds,/WEB-INF/
>> velocity/templates/emails
>> ...
>>
>> If you are now familiar with the code you might be in a better position to
>> see why I have to shut down for it to be picked up.
>>
>
> This could be your issue: http://stackoverflow.com/a/8656527/696632
>
> Michael
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reloading resources adding new macros

Greg Huber
In reply to this post by Michael Osipov
If someone could point me in the right direction on where it reloads the
macro names in the code, I could have a look myself at fixing it.

Cheer Greg

On 4 January 2017 at 17:34, Michael Osipov <[hidden email]> wrote:

> Am 2017-01-04 um 14:43 schrieb Greg Huber:
>
>> The was one issue that has been around for ages, and I am not sure if it
>> is
>> possible to fix it.
>>
>> If I have added a new macro into a velocity template file loaded via a
>> resource loader, I have to shut down the container (tomcat) and restart
>> for
>> it to be picked up.  I will allow the contents of the macro to be changed
>> but not a new macro.  I did try to see if I could fix it but without much
>> success.
>>
>> my velocity.properties :
>> ..
>> webapp.resource.loader.description=Webapp Resource Loader
>> webapp.resource.loader.class=rendering.velocity.WebappResourceLoader
>> webapp.resource.loader.cache=true
>> webapp.resource.loader.path=/WEB-INF/velocity,/WEB-INF/veloc
>> ity/templates,/WEB-INF/velocity/templates/feeds,/WEB-INF/
>> velocity/templates/emails
>> ...
>>
>> If you are now familiar with the code you might be in a better position to
>> see why I have to shut down for it to be picked up.
>>
>
> This could be your issue: http://stackoverflow.com/a/8656527/696632
>
> Michael
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reloading resources adding new macros

Greg Huber
In reply to this post by Michael Osipov
Sorry, I have looked at this again and it does now reload correctly with
the new macros without the restart.  Please ignore my previous emails!!

Cheers Greg.

On 4 January 2017 at 17:34, Michael Osipov <[hidden email]> wrote:

> Am 2017-01-04 um 14:43 schrieb Greg Huber:
>
>> The was one issue that has been around for ages, and I am not sure if it
>> is
>> possible to fix it.
>>
>> If I have added a new macro into a velocity template file loaded via a
>> resource loader, I have to shut down the container (tomcat) and restart
>> for
>> it to be picked up.  I will allow the contents of the macro to be changed
>> but not a new macro.  I did try to see if I could fix it but without much
>> success.
>>
>> my velocity.properties :
>> ..
>> webapp.resource.loader.description=Webapp Resource Loader
>> webapp.resource.loader.class=rendering.velocity.WebappResourceLoader
>> webapp.resource.loader.cache=true
>> webapp.resource.loader.path=/WEB-INF/velocity,/WEB-INF/veloc
>> ity/templates,/WEB-INF/velocity/templates/feeds,/WEB-INF/
>> velocity/templates/emails
>> ...
>>
>> If you are now familiar with the code you might be in a better position to
>> see why I have to shut down for it to be picked up.
>>
>
> This could be your issue: http://stackoverflow.com/a/8656527/696632
>
> Michael
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reloading resources adding new macros

Greg Huber
In reply to this post by Michael Osipov
.....it does not remove macros names, will keep this in mind next time I do
template work and work out exactly why I need to restart (if I still have
to do it at all).

Cheers Greg

On 4 January 2017 at 17:34, Michael Osipov <[hidden email]> wrote:

> Am 2017-01-04 um 14:43 schrieb Greg Huber:
>
>> The was one issue that has been around for ages, and I am not sure if it
>> is
>> possible to fix it.
>>
>> If I have added a new macro into a velocity template file loaded via a
>> resource loader, I have to shut down the container (tomcat) and restart
>> for
>> it to be picked up.  I will allow the contents of the macro to be changed
>> but not a new macro.  I did try to see if I could fix it but without much
>> success.
>>
>> my velocity.properties :
>> ..
>> webapp.resource.loader.description=Webapp Resource Loader
>> webapp.resource.loader.class=rendering.velocity.WebappResourceLoader
>> webapp.resource.loader.cache=true
>> webapp.resource.loader.path=/WEB-INF/velocity,/WEB-INF/veloc
>> ity/templates,/WEB-INF/velocity/templates/feeds,/WEB-INF/
>> velocity/templates/emails
>> ...
>>
>> If you are now familiar with the code you might be in a better position to
>> see why I have to shut down for it to be picked up.
>>
>
> This could be your issue: http://stackoverflow.com/a/8656527/696632
>
> Michael
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reloading resources adding new macros

Christopher Schultz-2
In reply to this post by Greg Huber
Greg,

On 1/4/17 11:40 AM, Greg Huber wrote:
>> Velocity version?
>
> The latest version ie 2.0.
>
>> When you say you "shut down the container (tomcat)", >can you be more
> specific? Do you bounce the >application, or do you >terminate Tomcat and
> the JVM, >etc.?
>
> Terminate tomcat shutdown.sh and then restart it.

If you terminate the JVM and the new instance doesn't pick up your
changes, then something is terribly wrong. You must be loading files
from a place you didn't expect, or something similar.

>> Did you write your own WebappResourceLoader (and if >so, why)?
>
> Its a bit application so I do have my own version.
>
> I did read on a list that it was an issue.  Think Nathan
> answered the post???
>
> Maybe I have missed something in the code?
>
>
> public class WebappResourceLoader extends ResourceLoader {
Why not use the WebappResourceLoader provided by Velocity Tools?

-chris


signature.asc (924 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reloading resources adding new macros

Greg Huber
After some more testing it does reload, except it does not remove the old
macro names and methods.  I guess it does not store where the macros
originated, so it appends new ones?  I cannot remember the exact reason why
I started stopping & restarting, maybe I was changing the signature and it
was not picking up the correct version.

I should have checked it more before asking the question.

Cheers Greg

On 5 January 2017 at 16:28, Christopher Schultz <
[hidden email]> wrote:

> Greg,
>
> On 1/4/17 11:40 AM, Greg Huber wrote:
> >> Velocity version?
> >
> > The latest version ie 2.0.
> >
> >> When you say you "shut down the container (tomcat)", >can you be more
> > specific? Do you bounce the >application, or do you >terminate Tomcat and
> > the JVM, >etc.?
> >
> > Terminate tomcat shutdown.sh and then restart it.
>
> If you terminate the JVM and the new instance doesn't pick up your
> changes, then something is terribly wrong. You must be loading files
> from a place you didn't expect, or something similar.
>
> >> Did you write your own WebappResourceLoader (and if >so, why)?
> >
> > Its a bit application so I do have my own version.
> >
> > I did read on a list that it was an issue.  Think Nathan
> > answered the post???
> >
> > Maybe I have missed something in the code?
> >
> >
> > public class WebappResourceLoader extends ResourceLoader {
>
> Why not use the WebappResourceLoader provided by Velocity Tools?
>
> -chris
>
>
Loading...