44

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

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

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

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 の使用は避けたいと思います。

4

4 に答える 4

52

あなたは正しい道を進んでいます。いくつかのことを考慮に入れる必要があります。

通常は、親クラスローダーに存在するクラスが使用されます。したがって、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();
于 2012-08-01T12:47:42.243 に答える
9

あなたはほとんど解決策を書いています。次のコード フラグメントが役立つことを願っています。

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

に置き換えるv1.jarv2.jar、このコードはバージョン #2 をロードします。

于 2012-08-01T12:43:39.160 に答える
1

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

于 2016-02-13T19:26:53.647 に答える
0

両方のバージョンで何をどのように行うかによって異なりますが、一般的には、少なくとも 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を参照してください。

于 2012-08-01T12:43:56.923 に答える