2013-03-05 156 views
2

我正在使用URLClassLoader加載類。URLClassLoader無法加載Linux上的依賴關係

雖然我傳遞的文件的名稱已成功加載,但對於它所反對的類,則會引發NoClassDefFoundError。這兩個類都是不同的jar文件的一部分。

更奇怪的東西是相同的一段代碼在Windows上工作正常,但它在Linux上拋出錯誤。

這裏是我使用的代碼:

package com.pb.spectrum.lim.upgrade.common; 

import java.io.File; 
import java.io.FilenameFilter; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.net.URLClassLoader; 
import java.util.ArrayList; 
import java.util.List; 

public class ClassInvoker { 

public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
    if(args.length < 2){ 
     throw new IllegalArgumentException("First argument should be Class name. Second argument should be jar's directory. Rest of the arguments passed to main method of invoked class."); 
    } 

    File jarsDir = new File(args[1]); 
    if(!jarsDir.isDirectory()){ 
     throw new IllegalArgumentException("Second argument should point to jar's directory."); 
    } 

    URLClassLoader urlClassLoader = null; 

    List<URL> urls = new ArrayList<URL>(); 
    File[] files = jarsDir.listFiles(new FilenameFilter() { 
     @Override 
     public boolean accept(File dir, String name) { 
      return name.toLowerCase().endsWith(".jar"); 
     } 
    }); 

    for(File jarFile : files){ 
     urls.add(jarFile.toURI().toURL()); 
    } 
    urlClassLoader = new URLClassLoader(urls.toArray(new URL[urls.size()])); 

    Thread.currentThread().setContextClassLoader(urlClassLoader); 

    Object[] params = new String[args.length-2]; 

    // First 2 arguments are not required for class to be invoked. 
    System.arraycopy(args, 2, params, 0, params.length); 

    for(Object string : params){ 
     System.out.println("Param ---->" + (String)string); 
    } 

    Class clazz = urlClassLoader.loadClass(args[0]); 
    Method method = clazz.getMethod("main", new Class[]{String[].class}); 
    method.invoke(null, new Object[] {params}); 
} 
    } 

現在,如果我通過爲A.B.MyClass1它成功地加載到加載類,但它未能加載A.B.MyClass2這是在單獨的jar文件。

+0

當你System.out.println'urls'時你會得到什麼? – 2013-03-05 13:39:21

+0

@NarendraPathai我沒有使用classpath,我正在使用URLClassLoader – 2013-03-05 13:46:37

+0

@DumumRanatunga打印網址給出了預期的結果。所有我添加的jar文件都顯示在那裏。 – 2013-03-05 13:47:26

回答

0

嗯,我的問題解決了,但我不確定這個問題的原因。

總結:加載中引起問題罐子

序列。在我的特殊情況下,在將列表提供給URLClassLoader之前,排序jar的順序解決了這個問題。

但它提出了另外一個問題

下面是詳細信息

我有相同的封裝結構,像A·B兩個jar文件,但其中只有一個是有MyClass2。現在問題的原因是沒有MyClass2加載之前,有MyClass2和以某種方式(我不知道如何或爲什麼)(我不知道如何或爲什麼)加載的URLClassLoader看到第一個罐包A.B但沒有MyClass2類和拋出NoClassDefFoundError。排序後,首先裝載MyClass2的jar,然後使用ClassLoader打包查找類。

我不確定這種行爲。我自己對此感到困惑。