web-dev-qa-db-ja.com

Java-同じクラスの異なるバージョンをロードする方法は?

Javaクラスローダーについてたくさん読んだことがありますが、これまでのところ、この簡単な質問に対する答えを見つけることができませんでした:

Jarにcom.abc.Hello.classの2つのバージョンがあるv1.jarおよびv2.jar。アプリケーションで両方を使用したい。これを行う最も簡単な方法は何ですか?

私はそんなに単純であるとは思っていませんが、これらの線に沿った何かが素晴らしいでしょう:

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の使用を避けたい。

36
kms333

あなたは正しい道を進んでいます。あなたはいくつかのことを考慮に入れなければなりません。

通常は、親クラスローダーに存在するクラスが使用されます。したがって、2つのバージョンが必要な場合は、それらのクラスが存在してはなりません。

ただし、やり取りしたい場合は、リフレクションを使用するか、共通インターフェースを使用することもできます。だから私はこれをやります:

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

あなたはほとんど解決策を書きました。次のコードがお役に立てば幸いです。

ClassLoader cl = new URLClassLoader(new URL[] {new File("v1.jar").toURL()}, Thread.currentThread().getContextClassLoader());
Class<?> clazz = cl.loadClass("Hello");

置換v1.jar 沿って v2.jarそしてこのコードはバージョン#2をロードします。

7
AlexR

@heliosチェックアウトで受け入れられた回答のサンプル実装について github.com/atulsm/ElasticsearchClassLoader

0
Atul Soman

それは両方のバージョンでどのように処理するかと方法に依存しますが、一般的には、少なくとも2つのバージョンのクラスを異なるクラスローダーにロードしてから、Thread.contextClassloader()そしてプレイ...

http://www.javaworld.com/javaqa/2003-06/01-qa-0606-load.html および http://docs.Oracle.com/javase/を参照してくださいjndi/tutorial/beyond/misc/classloader.html

0
Andrey Borisov