我已经读了很多有关Java类加载器,但到目前为止,我还没有找到这个简单问题的答案:
我在坛子里v1.jar和v2.jar com.abc.Hello.class的两个版本。 我想在我的应用程序同时使用。 什么是这样做的最简单的方法是什么?
我不希望是简单的,但东西沿着这些路线将是真棒:
Classloader myClassLoader = [magic that includes v1.jar and ignores v2.jar]
Hello hello = myclassLoader.load[com.abc.Hello]
而在不同的类:
Classloader myClassLoader = [magic that includes v2.jar and ignores v1.jar]
Hello hello = myclassLoader.load[com.abc.Hello]
我想避免使用OSGi。
你会以正确的方式。 你必须采取一些东西进去。
正常的是使用中存在的父类加载器类。 所以,如果你想要两个版本的类必须不应该存在。
但是,如果你想交互时,您可以使用反射,甚至更好的通用接口。 所以我会做到这一点:
common.jar:
BaseInterface
v1.jar:
SomeImplementation implements BaseInterface
v2.jar:
OtherImplementation implements BaseInterface
command-line:
java -classpath common.jar YourMainClass
// you don't put v1 nor v2 into the parent classloader classpath
Then in your program:
loader1 = new URLClassLoader(new URL[] {new File("v1.jar").toURL()}, Thread.currentThread().getContextClassLoader());
loader2 = new URLClassLoader(new URL[] {new File("v2.jar").toURL()}, Thread.currentThread().getContextClassLoader());
Class<?> c1 = loader1.loadClass("com.abc.Hello");
Class<?> c2 = loader2.loadClass("com.abc.Hello");
BaseInterface i1 = (BaseInterface) c1.newInstance();
BaseInterface i2 = (BaseInterface) c2.newInstance();
你几乎写的解决方案。 我希望下面的代码片段会有所帮助。
ClassLoader cl = new URLClassLoader(new URL[] {new File("v1.jar").toURL()}, Thread.currentThread().getContextClassLoader());
Class<?> clazz = cl.loadClass("Hello");
更换v1.jar
通过v2.jar
这个代码将加载版本#2。
这取决于什么是ü要与两个版本,以及如何做,但一般至少可以负载2版本在不同的类加载器的类,然后设置Thread.contextClassloader()和play ...
看到http://www.javaworld.com/javaqa/2003-06/01-qa-0606-load.html和http://docs.oracle.com/javase/jndi/tutorial/beyond/misc/classloader.html
对于由@helios接受答案的样本实现结帐github.com/atulsm/ElasticsearchClassLoader