lundi 16 juillet 2018

Java: calling method from class in different ClassLoaders

I'm writting a web application that will run on Tomcat8, that should be able to update while it's still running.

In order to do that, it will create a new ClassLoader and load the whole API again on top of that, every time a given "reload" button is pressed.

// get the urls from the current loader
URLClassLoader loader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
urls.addAll(Arrays.asList(loader.getURLs()));

// get the urls from the tomcat loader
loader = (URLClassLoader) loader.getParent();
urls.addAll(Arrays.asList(loader.getURLs()));

URL urlArray[] = new URL[urls.size()];
urlArray = urls.toArray(urlArray);

// my loader
loader = new URLClassLoader(urlArray, loader.getParent());

// this will throw ClassCastException
// because the newInstance will not return the System object
// that this loader knows
System newSystem = (System) loader.loadClass(System.class.getCanonicalName()).newInstance();

But! The problem begins when I need to call a shutdown method from the running system that is about do die.
If I try to store the "system" in a variable, to be able to call shutdown later, I'll get a ClassCastException because, for Java, the System class I've loaded from that other ClassLoader is not the same thing as the System class Tomcat knows about.

How could I call the System.shutdown() I need from the servlet context? Or is there a very different approach to handle this kind of situation?





Aucun commentaire:

Enregistrer un commentaire