On the fly class loading with jars

空扰寡人 提交于 2019-12-12 04:06:19

问题


I've got a ClassLoader extending class with following method

@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);
    }
}

That as u can see uses defineClass() method from its parent - ClassLoader. The issue is when i'm trying to execute a class' (i recieve with my ClassLoader extension - let it be ru.xmppTesting.test.Disco) method getMethods() while getting an instance of this class i get the following

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

As far as i can see that is because class org.apache.http.Header could not be found as defined. Because it is not.

So here's a question:

how can and must i define and link this Header class (and lots of others from my .jar libs) along with definition of ru.xmppTesting.test.Disco and others similar to have them defined on the fly?


回答1:


If your are importing org.apache.http.Header from your dinamic loaded class, you need it to be accesible at your classpath.

If you don't want to load all the potentially needed jars on your classpath, you could try with a hack i have found 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

But, I must say, it could not be portable to some JVMs (not always the SystemClassLoader is a subclass of URLClassLoader)...

*EDIT: * In fact, as you have replaced the classloader with your own, perhaps you have some troubles...



来源:https://stackoverflow.com/questions/3811545/on-the-fly-class-loading-with-jars

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!