2013-10-25 55 views
1

我有三個Jar文件。所有jar文件都包含相同的類TestServicesImpl和相同方法displayWeLcomeMessage()但有不同的消息(輸出)displayWeLcomeMessage()。 實施例:調用具有相同packageName的相同方法來自不同的JAR

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"); 

     } 

我有一個主要應用,並且它包含罐子包括在內。我的主應用程序調用displayWeLcomeMessage()方法。

將第一個JAR添加到classpath中,並將第二個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的方法的消息。

因此,讓我知道背後的主要問題和解決方案。

回答

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中添加這個接口!

0

類加載器將選擇首先找到的類。如果你有10個具有相同類別的包,那麼只有那個類將被挑選出來,這是首先引入的。

相關問題