[ https://issues.apache.org/jira/browse/VELOCITY-196?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Henning Schmiedehausen closed VELOCITY-196. ------------------------------------------- > 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 > Assigned To: Velocity-Dev List > 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. - You can reply to this email to add a comment to the issue online. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]