Calling same Method having same packageName From Different JARs [duplicate]

孤人 提交于 2020-01-03 01:44:08

问题


I have three Jar files.All jar files contain Same class TestServicesImpl And Same Method displayWeLcomeMessage() But having different messages(output) of displayWeLcomeMessage(). Example :

public void displayWeLcomeMessage() {
        System.out.println("wecome msg of JAR version first");

    }

 public void displayWeLcomeMessage() {
            System.out.println("wecome msg of JAR version two");

        }

 public void displayWeLcomeMessage() {
            System.out.println("wecome msg of JAR version third");

        }

I have One main application and it contains jars included. My main application calls displayWeLcomeMessage() method.

first JAR is added in classpath and second JAR is loaded with custom classloader and invoke method displayWeLcomeMessage().

    File file  = new File("C:/Users/amitk/Desktop/Test_1.0.2.jar");
    @SuppressWarnings("deprecation")
    URL url = file.toURL();  
    URL[] urls = new URL[]{url};
    URLClassLoader  loader = new URLClassLoader(urls);

    Class classS = loader.loadClass("com.amit.servicesImpl.TestServicesImpl");
    Object object = classS.newInstance();
    Method getmsg = classS.getMethod("displayWeLcomeMessage");
     getmsg.invoke(object);

but it displays the same message as in method of JAR first. In my third JAR, i have changed the package name. that is com.amit.servicesImpl.TestServicesImpl is changed to com.amit.servicesImpl2.TestServicesImpl and this time it works properly that is message of method of JAR 3 is displayed here.

so let me know the main issue behind this.and solution for this.


回答1:


Maybe you have your JAR in your initial class loader. URLClassLoader will check existing class in parent class loader before checking in its own space.

1) You can extend and modify this behavior:

package com.mytool;

import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandlerFactory;
import java.util.HashMap;
import java.util.Map;

public class MyURLClassLoader extends URLClassLoader {

    private final Map<String, Class<?>> ourClasses = new HashMap<>();

    public MyURLClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }

    public MyURLClassLoader(URL[] urls) {
        super(urls);
    }

    public MyURLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {
        super(urls, parent, factory);
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = ourClasses.get(name);

            if (c == null) {
                // search in our paths
                try {
                    c = findClass(name);
                    ourClasses.put(name, c);
                } catch (ClassNotFoundException e) {
                    // ignore
                }
            }

            if (c == null) {
                c = findLoadedClass(name);
            }

            if (c != null) {
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }

            // default search
            return super.loadClass(name, resolve);
        }
    }
}

2) Or you can try to move our JAR and not load it at JVM start.

Note: Instead of using a full reflexivity, I'll use an interface loaded only by the initial classloader. Your object could implements it, and you'll be able to cast to this interface. If you do this with MyURLClassLoader, please don't add this interface in our dynamic loaded JAR!




回答2:


Classloader will pick that class which was found first. If you are having 10 packages having same class then only that class will be picked which was introduced first.



来源:https://stackoverflow.com/questions/19589648/calling-same-method-having-same-packagename-from-different-jars

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!