Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从不同的jar加载相同的类_Java_Classloader - Fatal编程技术网

Java 从不同的jar加载相同的类

Java 从不同的jar加载相同的类,java,classloader,Java,Classloader,我有一个新的小Swing项目,我需要从两个不同的jars加载相同的类。这些jars是第三方,所以我没有源代码 例如,我需要从两个JAR加载myClass。 jar1.jar jar2.jar 简单地说,我需要做的是: public void doMyClassLogicVersion1() { Loader = // here i need to load jar1.myClass. // myClass need a two params to initialize it i

我有一个新的小Swing项目,我需要从两个不同的jars加载相同的类。这些jars是第三方,所以我没有源代码

例如,我需要从两个JAR加载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
}

所以我可以这样做,我知道这样做对我不好,但我真的需要这样做。

是的,你可以这样做。为了避免问题,我建议您不要将任何jar放在常规类路径中,创建两个不同的线程,并在启动它们之前将每个线程的ContextClassLoader设置为相应的jar。

您可以相对轻松地将新代码加载到新的类加载器中:

案例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();
}
public void doMyClassLogicVersion1(){
ClassLoader=URLClassLoader.newInstance(
新URL[]{yourURL1},
getClass().getClassLoader()
);
Class clazz=Class.forName(“mypackage.MyClass”,true,loader);
Class clazz=Class.forName(“mypackage.MyClass”,true,loader);
Class clazz=Class.forName(“mypackage.MyClass”,true,loader);
//避免Class.newInstance,因为它是邪恶的。
Constructor=runClass.getConstructor();
Object obj=ctor.newInstance();
String methodName=“getName”;
java.lang.reflect.Method;
试一试{
method=clazz.getMethod(methodName,param1.class,param2.class,…);
}捕获(安全异常e){
// ...
}捕获(无此方法例外){
// ...
}
试一试{
调用(obj,arg1,arg2,…);
}捕获(IllegalArgumentException e){
// ...
}捕获(非法访问例外e){
// ...
}捕获(调用TargetException e){
// ...
}
}
public void doMyClassLogicVersion2(){
ClassLoader=URLClassLoader.newInstance(
新URL[]{yourURL2},
getClass().getClassLoader()
);
Class clazz=Class.forName(“mypackage.MyClass”,true,loader);
//避免Class.newInstance,因为它是邪恶的。
Constructor=runClass.getConstructor();
Object obj=ctor.newInstance();
String methodName=“getName”;
java.lang.reflect.Method;
试一试{
method=clazz.getMethod(methodName,param1.class,param2.class,…);
}捕获(安全异常e){
// ...
}捕获(无此方法例外){
// ...
}
试一试{
调用(obj,arg1,arg2,…);
}捕获(IllegalArgumentException e){
// ...
}捕获(非法访问例外e){
// ...
}捕获(调用TargetException e){
// ...
}
}

对已删除问题的回答:为什么选择URLClassLoader.newInstance?URLClassLoader.newInstance为指定的URL和默认父类加载器创建URLClassLoader的新实例。如果安装了安全管理器,则此方法返回的URLClassLoader的loadClass方法将在加载类之前调用SecurityManager.checkPackageAccess。来源:谢谢mohammad,但我仍然需要调用包含加载类的特定方法。因此,这将与您的代码一起提供。myClass构造函数showd包含两个PATAM。这两个类是否具有相同的父类?如果他们有,那么您可以在我的代码中用Runnable替换父类。否则,如果他们没有公共父类,您仍然可以通过反射来完成。如果它对您有效,请不要忘记将其标记为answer!
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) {
      // ...
    }
}