自定义类加载器在listFilesAndDirs()方法调用中返回NoSuchMethodException

时间:2014-05-19 11:20:43

标签: java class exception object classloader

我正在尝试使用自己的自定义类加载器调用org.apache.commons.io.FileUtils的方法listFilesAndDirs()。但它返回NoSuchMethodException。

用于方法调用的代码。

MyLoader c=new MyLoader();
Class cls=c.loadClass("org.apache.commons.io.FileUtils");
//to display the available methods
Method m[] = cls.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
  System.out.println(m[i].toString());

// to get a listFilesAndDirs method
Method me=cls.getMethod("listFilesAndDirs",new Class[] { File.class, IOFileFilter.class,
            IOFileFilter.class });

用于类加载器的代码

public class MyLoader extends ClassLoader {
private  String classPath;
public MyLoader()
{

}
private String jarFile = "D:/Project/lib/commons-io-2.4.jar";;          //Path to the jar file  
private Hashtable classes = new Hashtable(); //used to cache already defined classes  

public Class loadClass(String className) throws ClassNotFoundException {  

return findClass(className);  
}  

public Class findClass(String className) {  
//System.out.println(className+" is loaded by Custom class Loader");


byte classByte[];  
Class result = null;  

result = (Class) classes.get(className); //checks in cached classes  
if (result != null) {  
    return result;  
}  



try {
    JarFile jar = new JarFile(jarFile);  
    classPath=className.replaceAll("\\.", "/");
    JarEntry entry = jar.getJarEntry(classPath + ".class"); 
    if(entry==null)
    {
         return findSystemClass(className);  
    }
    else
    {

    InputStream is = jar.getInputStream(entry);  
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();  
    int nextValue = is.read();  
    while (-1 != nextValue) {  
        byteStream.write(nextValue);  
        nextValue = is.read();  
    }  

    classByte = byteStream.toByteArray(); 
    result = defineClass(className, classByte, 0, classByte.length, null);  
    classes.put(className, result);  
    return result;  
    }
} catch (Exception e) {  
    return null;  
}  


 } 
 }

调用cls.getDeclaredMethods()将返回方法 org.apache.commons.io.FileUtils.listFilesAndDirs(java.io.File的,org.apache.commons.io.filefilter.IOFileFilter,org.apache.commons.io.filefilter.IOFileFilter)

但cls.getMethod(&#34; listFilesAndDirs&#34 ;, new Class [] {File.class,IOFileFilter.class,             IOFileFilter.class}); 返回以下错误

java.lang.NoSuchMethodException:org.apache.commons.io.FileUtils.listFilesAndDirs(java.io.File,org.apache.commons.io.filefilter.IOFileFilter,org.apache.commons.io.filefilter.IOFileFilter )     at java.lang.Class.getDeclaredMethod(Class.java:1937)     在Sample.main(Sample.java:30)

1 个答案:

答案 0 :(得分:1)

因此,getDeclaredMethods()显示相关课程具有所需的方法listFilesAndDirs(java.io.File,org.apache.commons.io.filefilter.IOFileFilter,org.apache.commons.io.filefilter.IOFileFilter)

BUT

参数类型与传递给cls.getMethod("listFilesAndDirs",new Class[]{...})的参数类型不同,即使它们似乎引用了正确的类。

您编译的代码使用上下文类加载器中的org.apache.commons.io.filefilter.IOFileFilter类,而cls需要来自自定义类加载器的相同类。

使其工作的一种方法是从自定义类加载器加载IOFileFilter,然后在调用getMethod时将该类用作第二和第三项。

Class ioFileFilterClass = c.loadClass( "org.apache.commons.io.filefilter.IOFileFilter" );
Method me = cls.getMethod( "listFilesAndDirs", new Class[] { File.class, ioFileFilterClass, ioFileFilterClass} );

它将解决这个特殊问题,但每次尝试访问自定义类加载器加载的类和方法时,都必须编写类似的代码。