簡體   English   中英

從不同的罐子裝載相同的類

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM