在飞行类装载罐子

时间:2010-09-28 09:48:43

标签: java jar classloader

我有一个使用以下方法

的ClassLoader扩展类
@Override
public Class<?> findClass(String className) throws ClassNotFoundException {
    try {
        /**
        * Get a bytecode from file
        */

        byte b[] = fetchClassFromFS(pathtobin + File.separator
            + className.replaceAll("\\.", escapeSeparator(File.separator)) + ".class");
        return defineClass(className, b, 0, b.length);
    } catch (FileNotFoundException ex) {
        return super.findClass(className);
    } catch (IOException ex) {
        return super.findClass(className);
    }
}

你可以看到它使用其父类的ClassClass()方法 - ClassLoader。问题是当我尝试执行一个类'(我接受我的ClassLoader扩展 - 让它成为ru.xmppTesting.test.Disco)方法getMethods(),同时获取此类的实例我得到以下

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/Header
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
    at java.lang.Class.privateGetPublicMethods(Unknown Source)
    at java.lang.Class.getMethods(Unknown Source)
    at DOTGraphCreator.createGraphFromClasses(DOTGraphCreator.java:85)
    at DOTGraphCreator.generateDotGraphFile(DOTGraphCreator.java:56)
    at DOTGraphCreator.main(DOTGraphCreator.java:46)
Caused by: java.lang.ClassNotFoundException: org.apache.http.Header
    at java.lang.ClassLoader.findClass(Unknown Source)
    at SourceClassLoader.findClass(SourceClassLoader.java:27)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 7 more

据我所知,这是因为无法按定义找到类org.apache.http.Header。因为不是。

所以这是一个问题:

如何定义和链接此Header类(以及我的.jar库中的许多其他类)以及ru.xmppTesting.test.Disco的定义以及其他类似的动态定义和链接?

1 个答案:

答案 0 :(得分:0)

如果您要从已加载dinamic的类导入 org.apache.http.Header ,则需要在类路径中访问它。

如果您不想在类路径中加载所有可能需要的jar,可以尝试使用我发现的hack here

import java.lang.reflect.*;
import java.io.*;
import java.net.*;

public class ClassPathHacker {

private static final Class[] parameters = new Class[]{URL.class};

public static void addFile(String s) throws IOException {
    File f = new File(s);
    addFile(f);
}//end method

public static void addFile(File f) throws IOException {
    addURL(f.toURL());
}//end method


public static void addURL(URL u) throws IOException {

    URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
    Class sysclass = URLClassLoader.class;

    try {
        Method method = sysclass.getDeclaredMethod("addURL",parameters);
        method.setAccessible(true);
        method.invoke(sysloader,new Object[]{ u });
    } catch (Throwable t) {
        t.printStackTrace();
        throw new IOException("Error, could not add URL to system classloader");
    }//end try catch

}//end method

}//end class

但是,我必须说,它无法移植到某些JVM(并不总是SystemClassLoader是URLClassLoader的子类)...

* 编辑:* 事实上,正如您已经用自己的类加载器替换了类加载器,也许您有一些麻烦......