如何设置上下文类加载器的类路径以进行运行时编译? [英] How to set up the context class loader's classpath for runtime compilation?
问题描述
我想在运行时在weblogic 10.3服务器中编译和加载新类.类加载似乎有些简单:
I would like to compile and load new classes at runtime within a weblogic 10.3 server. Class loading seems to be somewhat straightforward:
class ClassFileManager
extends ForwardingJavaFileManager<StandardJavaFileManager> {
Map<String, JavaClassObject> classes = new HashMap<String, JavaClassObject>();
public ClassFileManager(StandardJavaFileManager standardManager) {
super(standardManager);
}
@Override
public ClassLoader getClassLoader(Location location) {
return new SecureClassLoader(currentThread().getContextClassLoader()) {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] b = classes.get(name).getBytes();
return super.defineClass(name, b, 0, b.length);
}
};
}
@Override
public JavaFileObject getJavaFileForOutput(
Location location, String className, Kind kind, FileObject sibling)
throws IOException {
JavaClassObject result = new JavaClassObject(className, kind);
classes.put(className, result);
return result;
}
}
执行类加载的最简单方法似乎是初始化 SecureClassLoader
,并使其使用 contextClassLoader
作为父级.
The simplest way to perform class loading seems to be to initialise a SecureClassLoader
and have it use the contextClassLoader
as the parent.
但是当为JDK的运行时编译器设置 -classpath
选项时,我似乎找不到字符串形式的上下文类路径".以下是一些可以足够好"
But when setting up the -classpath
option for the JDK's runtime compiler, I cannot seem to find a "context classpath" in a string form. The following is a bit of a hack that works "well enough":
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
ClassFileManager fileManager =
new ClassFileManager(compiler.getStandardFileManager(null, null, null));
List<String> options = new ArrayList<String>();
options.add("-classpath");
options.add(System.getProperty("java.class.path") + ";" +
getClass().getProtectionDomain()
.getCodeSource().getLocation()
.toURI().toString()
.replace("file:/", "").replace("/", "\\"));
但是它不会生成上下文类加载器的完整类路径.我如何可靠地做到这一点?我可以吗?
But it doesn't generate the complete class path of the context class loader. How can I do it, reliably? Can I?
推荐答案
WebLogic 10.3.6具有相当复杂的 ClassLoader
实现.幸运的是,用于Web应用程序的类加载器公开了 getClassPath
方法.
WebLogic 10.3.6 has a fairly complex ClassLoader
implementation. Fortunately the classloader used for web applications exposes a getClassPath
method.
ClassLoader cl = Thread.currentThread().getContextClassLoader();
String classPath = ((weblogic.utils.classloaders.GenericClassLoader)cl).getClassPath();
// Once we have a classpath it's standard procedure
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager sfm = compiler.getStandardFileManager(null, null, null);
List<String> optionList = new ArrayList<String>();
optionList.addAll(Arrays.asList("-classpath", classPath));
compiler.getTask(null, sfm, null, optionList, null, sources).call();
这篇关于如何设置上下文类加载器的类路径以进行运行时编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!