You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by "David Campbell (JIRA)" <de...@velocity.apache.org> on 2011/02/24 01:55:38 UTC

[jira] Commented: (VELOCITY-196) ClasspathResourceLoader uses wrong ClassLoader

    [ https://issues.apache.org/jira/browse/VELOCITY-196?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12998637#comment-12998637 ] 

David Campbell commented on VELOCITY-196:
-----------------------------------------

I find that the fix doesn't work, at least from an EJB deployed in the Glassfish application server.  It can't load its templates.

> ClasspathResourceLoader uses wrong ClassLoader
> ----------------------------------------------
>
>                 Key: VELOCITY-196
>                 URL: https://issues.apache.org/jira/browse/VELOCITY-196
>             Project: Velocity
>          Issue Type: Bug
>          Components: Engine
>    Affects Versions: 1.3.1
>         Environment: Operating System: other
> Platform: Other
>            Reporter: Charles Oliver Nutter
>             Fix For: 1.5
>
>         Attachments: ClasspathFix.patch, patch.txt
>
>
> I see the following problems with ClasspathResourceLoader:
> 1. It loads templates using the ClassLoader it was loaded in, which in many
> cases will be the top-level or a high-level ClassLoader within an appserver
> 2. Individual applications within the server almost always are given their own
> contextual ClassLoader. In Tomcat, for example, each webapp has its own loader.
> 3. Each webapp should be able to package templates in jars to be put in
> WEB-INF/lib and have Velocity load them correctly.
> 4. Each webapp should not have to put velocity-xxx.jar in their WEB-INF/lib to
> be able to use Velocity.
> 5. Therefore, Velocity should be able to load templates using the contextual
> ClassLoader appropriate for the *caller*
> ClasspathResourceLoader uses getClass().getClassLoader() to look for templates.
> If Velocity is loaded at the system or server level, and a webapp hopes to use
> this method to load its own jarred templates, it will fail as it did for me.
> The fix is terribly simple, and I think it makes sense to apply it directly to
> ClasspathResourceLoader, or at least provide a ThreadContextResourceLoader, as I
> have done:
> In ClasspathResourceLoader.getResourceStream(), change:
> ClassLoader classLoader = this.getClass().getClassLoader();
> to:
> ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
> This will cause the resource loading to look first at the caller's level
> (webapp) and if not found, move up the ClassLoader chain. I believe this is the
> appropriate way to handle loading templates as resources. From the documentation
> for getContextClassLoader():
> ...
>      * Returns the context ClassLoader for this Thread. The context
>      * ClassLoader is provided by the creator of the thread for use
>      * by code running in this thread when loading classes and resources.
>      * If not set, the default is the ClassLoader context of the parent
>      * Thread. The context ClassLoader of the primordial thread is
>      * typically set to the class loader used to load the application.
> ...
> The resource should be loaded from the ClassLoader that the creator of the
> calling thread intended...not from the classloader that loaded Velocity. Also
> keep in mind this change would not break loading from the system classpath...it
> would just include contextual ClassLoaders in the lookup process.
> I will look into creating a patch if it would be useful, but it's a one-line fix.

-- 
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@velocity.apache.org
For additional commands, e-mail: dev-help@velocity.apache.org