我有一个新的小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
}
我也可以这样做,我知道这不好,但我真的需要。
答案 0 :(得分:2)
您可以相对轻松地将新代码加载到新的类加载器中:
案例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) {
// ...
}
}
答案 1 :(得分:0)
是的,你可以做到。为避免出现问题,我建议您不要将任何jar放入常规CLASSPATH中,创建2个不同的线程,并在启动它们之前将每个线程的ContextClassLoader设置为相应的jar。