使用ClassLoader.getSystemClassLoader()

时间:2016-10-22 14:05:38

标签: java classloader

在tomcat中,我通过使用类加载器加载HelloWorld。

  sb.append("package XXXX.XXXXX.XXXX.freemarkerjob;\n");
        sb.append("import XXXX.XXXXX.XXXX.freemarkerjob.DoStuff;\n");
        sb.append("public class HelloWorld implements DoStuff {\n");
        sb.append("    public void doStuff() {\n");
        sb.append("        System.out.println(\"Hello world\");\n");
        sb.append("    }\n");
        sb.append("}\n");


Class<?> helloClass = InMemoryJavaCompiler.compile("XXXX.XXXXX.XXXX.HelloWorld", sb.toString(), optionList);

我发现如果我使用Thread.currentThread()。getContextClassLoader()作为DynamicClassLoader的父级,那么我可以成功加载该类,但是如果我使用(ClassLoader.getSystemClassLoader(),则抛出classnotfoundexception)当调用方法cl.loadClass(className);,它无法加载HelloWorld实现它的接口DoStuff。 我需要知道为什么SystemClassLoader无法加载接口?

DynamicClassLoader cl = new DynamicClassLoader(Thread.currentThread().getContextClassLoader());


DynamicClassLoader cl = new DynamicClassLoader(ClassLoader.getSystemClassLoader());


    Class<?> helloClass = InMemoryJavaCompiler.compile("XXXX.XXXXX.XXXX.HelloWorld", sb.toString(), optionList);



public static Class<?> compile(String className, String sourceCodeInText, Iterable<String> options) throws Exception {

This one successfully 
         DynamicClassLoader cl = new DynamicClassLoader(Thread.currentThread().getContextClassLoader());

This one failed
        //     DynamicClassLoader cl = new DynamicClassLoader(ClassLoader.getSystemClassLoader());

 cl.loadClass(className);

}

package XXXX.XXXXX.XXXX.dynamicjava;
import java.util.HashMap;
import java.util.Map;
public class DynamicClassLoader extends ClassLoader {
    private Map<String, CompiledCode> customCompiledCode = new HashMap<>();
    public DynamicClassLoader(ClassLoader parent) {
        super(parent);
    }
    public void setCode(CompiledCode cc) {
        customCompiledCode.put(cc.getName(), cc);
    }
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        CompiledCode cc = customCompiledCode.get(name);
        if (cc == null) {
          Class<?> curClass = super.findClass(name);
            if (curClass == null) {
                return null;
            } else {
                return curClass;
            }
        }
        byte[] byteCode = cc.getByteCode();
        return defineClass(name, byteCode, 0, byteCode.length);
    }
}

1 个答案:

答案 0 :(得分:0)

您的界面(DoStuff)未由SystemClassLoader加载,通常由应用程序类加载器加载。

如果您想在DoStuff的上下文中使用HelloWorld,请使用以下内容,

DynamicClassLoader cl = new DynamicClassLoader(DoStuff.class.getClassLoader());