#java #classloader
#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); , которому не удалось загрузить интерфейс doStuff , в котором HelloWorld его реализует.
что мне нужно знать, почему 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:
Ваш интерфейс (doStuff) не загружается SystemClassLoader, обычно он загружается загрузчиками классов приложений.
Если вы хотите сделать HelloWorld доступным в контексте doStuff, используйте следующее,
DynamicClassLoader cl = новый DynamicClassLoader(doStuff.class.getClassLoader());