Can I dynamically unload and reload (other versions of the same) JAR?

拥有回忆 提交于 2019-12-17 15:44:59

问题


I am writing a server program which is used to run unit tests of an API (displaying lots of information and providing web access to control / monitor the whole thing)...

This API is known to the server during compile time and is provided as a JAR.

To be able to compare between unit test results of different versions of the API (without restarting the server), I want to be able to unload the 'current' version of the API, and to reload a newer one (or an older one).

I don't want to use URLClassLoader and invoke every single method by name
( using getDeclaredMethod("someMethod") ),
because the server heavily depends on the API and it would be complicated to 'wrap' every method call in such dirty way.

I was thinking: Since all interfaces of all versions of the JAR are same, couldn't I do it by somehow reloading an other version of the JAR (without that by-name-invokation?).

Note: I am using latest Java SE (6) and Java EE (5).

If you think, what I'm trying to achieve is not possible, please suggest a 'workaround' or a different concept.


回答1:


I think if you load a class using

Class.forName(clsname, init, classloader); 

(Javadoc here) you will get an instance of the class provided by the given classloader. Everything loaded because of that class will also be loaded via the same classloader.

As long as you're very careful with the objects instantiated from this point on (to allow for GC), you should be able to reload different versions. I did this once before with Java 1.3, it took a lot of debugging, but at the end I had a "bootstrap" application that loaded a Runnable class by name and was able to "soft-restart" by instantiating a new classloader against a different URL and going again.




回答2:


You could programatically modify your classpath to reflect your JAR changes. Here is how I would do it:

  URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        Method m = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
        m.setAccessible(true);
        m.invoke(urlClassLoader, jarFile.toURI().toURL());
        String cp = System.getProperty("java.class.path");
        if (cp != null) {
            cp += File.pathSeparatorChar + jarFile.getCanonicalPath();
        } else {
            cp = jarFile.toURI().getPath();
        }
        System.setProperty("java.class.path", cp);

where jarFile is the version of the jar you want to use/overwrite.




回答3:


You can use the opensource package : JclLoader which helps in loading different versions of the same jar. This was also a need in one of our systems to do testing .

Link: http://sourceforge.net/projects/jcloader/




回答4:


OSGi is a framework that will allow you to do it. JSR 277 the Java Module System is designed for doing that as well (I think). I have not followed the OSGi -vs- JSR 277 debate, so I don't know f they are trying to marge them at all.

You can roll your own with class loaders, but it'll be less "fun".




回答5:


Yes. I've seen it done at a NFJS conference. It's how things like web containers support hot deployment of applications and involves taking advantage of the scope of class loaders. In order to accomplish it you need to create a new class loader and use that to load the library in question.. then throw the loader away (or not) and create another when you want to reload. You may also have to override the behaviour of the class loader (I remember something about class loaders getting classes via their parent first by default.) Also, I remember a warning that objects created by different class loaders are not compatible (not of the same type) with each other even if the .class file is exactly the same.

It's mostly deep magic to me though. ;-)




回答6:


Probably not. The Java classloader doesn't really support run-time loading; even the available classloaders are hacks that use a proxy object.



来源:https://stackoverflow.com/questions/728140/can-i-dynamically-unload-and-reload-other-versions-of-the-same-jar

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!