2013-03-05 57 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打包查找类。

我不确定这种行为。我自己对此感到困惑。

相关问题