Java - 如何加载不同版本的同一个类? [英] Java - how to load different versions of the same class?

查看:965
本文介绍了Java - 如何加载不同版本的同一个类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了很多关于Java类加载器,但到目前为止我没有找到这个简单的问题的答案:



我有两个版本的 jars v1.jar v2.jar 中的.com.abc.Hello.class 。我想在我的应用程序中使用。这是最简单的方法是什么?



我不期望这么简单,但沿着这些线的东西将是真棒:

 类加载器myClassLoader = [魔术包括v1.jar和忽略v2.jar] 
Hello hello = myclassLoader.load [com.abc.Hello]

在不同的类别中:

  Classloader myClassLoader = [包含v2.jar和忽略v1.jar的魔法] 
Hello hello = myclassLoader.load [com.abc.Hello]



我想避免使用OSGi。

解决方案>

你会走的正确的路。你必须考虑一些事情。



正常的是使用父类装载器中存在的类。所以如果你想要两个版本,那些类不能存在。



但是如果你想互动,你可以使用反射,甚至更好的一个通用接口。所以我会这样做:

  common.jar:
BaseInterface

v1。 jar:
SomeImplementation实现BaseInterface

v2.jar:
OtherImplementation implements BaseInterface

命令行:
java -classpath common.jar YourMainClass
//你不会把v1和v2放入父类classloader classpath

然后在你的程序中:

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();


I have read a lot about Java classloaders, but so far I have failed to find an answer for this simple question:

I have two versions of com.abc.Hello.class in jars v1.jar and v2.jar. I want to use both in my application. What is the simplest way of doing this ?

I don't expect to be that simple, but something along these lines would be awesome :

Classloader myClassLoader = [magic that includes v1.jar and ignores v2.jar]
Hello hello = myclassLoader.load[com.abc.Hello]

And in a different class :

Classloader myClassLoader = [magic that includes v2.jar and ignores v1.jar]
Hello hello = myclassLoader.load[com.abc.Hello]

I would like to avoid using OSGi.

解决方案

You're going the right way. You must take some things into account.

The normal thing is classes that exist in parent classloaders are used. So if you want two versions those classes must not be there.

But if you want to interact you can use reflection, or even better a common interface. So I'll do this:

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();

这篇关于Java - 如何加载不同版本的同一个类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆