views:

48

answers:

1

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?

A: 

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...

Tomas Narros
That's what i thought of right away. But my aim is to make a simple app which loads selected class (for annotations and methods parsing purposes) and do not burden one with knowing what this class consists of and what it does import and what it does at all. Maybe u could provide a better approach to realization of that?
endarkened
@endarkened: This would imply analyzing the imported classes at loading time, and finding dinamically where in your file system is a JAR with the required classes, and also resolve posible secondary dependencies from this JAR imported... I think it's more than quite dificult to get. Let me see if I can find something.
Tomas Narros