我有三个Jar文件。所有jar文件都包含Same class TestServicesImpl和Same Method displayWeLcomeMessage()但是有不同的displayWeLcomeMessage()消息(输出)。 示例:
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");
}
我有一个主要应用程序,它包含包含的jar。我的主应用程序调用displayWeLcomeMessage()方法。
在类路径中添加第一个JAR,第二个JAR使用自定义类加载器和调用方法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);
但它首先显示与JAR方法相同的消息。 在我的第三个JAR中,我更改了包名称。 那是 com.amit.servicesImpl.TestServicesImpl 更改为 com.amit.servicesImpl2.TestServicesImpl 这次它正常工作,这里显示JAR 3方法的消息。
所以让我知道这背后的主要问题。解决方案。
答案 0 :(得分:2)
也许你在初始的类加载器中有你的JAR。 在检查自己的空间之前,URLClassLoader将检查父类加载器中的现有类。
1)您可以扩展和修改此行为:
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)或者你可以尝试移动我们的JAR而不是在JVM启动时加载它。
注意:强> 我将使用一个接口,而不是使用完全反身性 仅由初始类加载器加载。您的对象可以实现它,您将能够转换为此接口。如果您使用MyURLClassLoader执行此操作,请不要在我们动态加载的JAR中添加此接口!
答案 1 :(得分:0)
Classloader将选择首先找到的类。如果你有10个具有相同类的包,那么只会选择首先引入的类。