[英]Loading same class from different jars
我有一個新的小Swing項目,我需要從兩個不同的jarsm加載相同的類這些罐子是第三方所以我沒有源代碼。
例如,我需要從兩個罐子加載myClass。 jar1.jar jar2.jar
只是我需要做的事情:
public void doMyClassLogicVersion1() {
Loader = // here i need to load jar1.myClass.
// myClass need a two params to initialize it in the normal case
// also i need to access its static members
// do the logic of myClass version1
}
public void doMyClassLogicVersion2() {
Loader = // here i need to load jar2.myClass.
// myClass need a two params to initialize it in the normal case
// also i need to access its static members
// do the logic of myClass version2
}
所以我可以這樣做,我知道這不好,但我真的需要。
您可以相對輕松地將新代碼加載到新的類加載器中:
情況1:如果您的類在當前上下文中具有公共父接口(或類),例如Runnable,則可以使用以下代碼:
public void doMyClassLogicVersion1() {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { yourURL1 },
getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class);
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
doRun.run();
}
public void doMyClassLogicVersion2() {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { yourURL2 },
getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class);
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
doRun.run();
}
案例2:如果班級不共享一個共同的父母:
public void doMyClassLogicVersion1() {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { yourURL1 },
getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
// Avoid Class.newInstance, for it is evil.
Constructor<?> ctor = runClass.getConstructor();
Object obj = ctor.newInstance();
String methodName = "getName";
java.lang.reflect.Method method;
try {
method = clazz.getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) {
// ...
} catch (NoSuchMethodException e) {
// ...
}
try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) {
// ...
} catch (IllegalAccessException e) {
// ...
} catch (InvocationTargetException e) {
// ...
}
}
public void doMyClassLogicVersion2() {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { yourURL2 },
getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
// Avoid Class.newInstance, for it is evil.
Constructor<?> ctor = runClass.getConstructor();
Object obj = ctor.newInstance();
String methodName = "getName";
java.lang.reflect.Method method;
try {
method = clazz.getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) {
// ...
} catch (NoSuchMethodException e) {
// ...
}
try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) {
// ...
} catch (IllegalAccessException e) {
// ...
} catch (InvocationTargetException e) {
// ...
}
}
是的,你可以做到。 為避免出現問題,我建議您不要將任何jar放入常規CLASSPATH中,創建2個不同的線程,並在啟動它們之前將每個線程的ContextClassLoader設置為相應的jar。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.