I have a plugin system realized in Tomcat 7 which loads dynamically classes of these plugins (reloadable via a custom classloader). Unfortunately, if a plugin has a JSP which uses a class which belongs to this plugin, it cannot find this class. This seems to be the correct behavior as we have the Tomcat classloader hierarchy and my custom classloader is at the bottom.
Nevertheless, with this hacky thing I can make the classes available to the JSPs:
URLClassLoader webappClassloader = (URLClassLoader)Thread.currentThread().getContextClassLoader();
Method addURLMethod = webappClassloader.getClass().getDeclaredMethod("addURL", URL.class);
addURLMethod.setAccessible(true);
for(String url : pluginFolders)
addURLMethod.invoke(webappClassloader, new URL("file://" + url));
Please note, that the plugins are not in the WEB-INF/classes directory.
This is all great but now a class can only be loaded once (see also this). In order to make the plugins updatable (without restarting the whole webapp) I am using a custom classloader. But I wasn't able to set this classloader to be used by Jasper (I tried Thread.currentThread().setContextClassLoader()
which had no effect). I digged into the source of Jasper and it seems like it should be possible to set a custom classloader. But I have no idea how to achieve this from a servlet.
Maybe you can give me an answer to one of the following questions?
- Is it possible to get e.g. JspCompilationContext within a servlet?
- I've read something about a custom JSPServlet. How would this be done?
- Do you have a better idea of how to set the classloader?
Thanks in advance!