SecureClassLoader doesn't find depending interfaces

57 views Asked by At

I use the JavaCompiler to create a class dynamical. This class implements a given interface. for the JavaCompiler I can create a correct class path so the compiler can compile my class.

 //creating the classpath from parent application to be same as the runtime's
 ClassLoader dummyc=getClass().getClassLoader();
 URLClassLoader urlClassLoader=(URLClassLoader)dummyc;
 URL[] urls=urlClassLoader.getURLs();
 String classpath = "";
 for (URL i : urls) {
     classpath += ";" + i.getPath().substring(1);
 }

I use an anonym classloader:

   return new SecureClassLoader() {
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            byte[] b = javaClassObject.getBytes();
            return super.defineClass(name, javaClassObject.getBytes(), 0, b.length);
        }
    };

to load the compiled class but when I call the loadClass method I get this error: NoClassDefFoundError: refac/IBewertungsAlgorithmus (wrong name: refac/MyClass)

Is it possible to set the same classpath I set for the compiler task for the class loader?

1

There are 1 answers

0
Tokra On

I found the solution.
I need to use not only the SecureClassLoader I also need the ClassLoader of the parent class with all of it's dependencies.

public ClassLoader getClassLoader(Location location) {
    ClassLoader cl = DynamicCompiler.class.getClassLoader(); 
    return new SecureClassLoader() {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
                byte[] b = javaClassObject.getBytes();
                if (name.contains("MyClass")){
                    return super.defineClass(name, javaClassObject.getBytes(), 0, b.length);
                } else {
                    return cl.loadClass(name);
                }

            }
        };
    }

The first call of findclass searches for the compiled class, so I have to call defineClass of the SecureclassLoader.
The following calls are for the dependencies of the compiled class. To load these classes you need the loadClass method of the parent classloader.