我希望在Weblogic 10.3服务器上运行时编译和加载新的类。类加载似乎有点简单:
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
作为父级。但是,在为JDK的运行时编译器设置
-classpath
选项时,我似乎找不到以字符串形式表示的 "context classpath"。下面这个方法有点取巧,但足够好用: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("/", "\\"));
但它无法生成上下文类加载器的完整类路径。我怎样才能可靠地做到这一点?我能吗?
if (classes.get(name)==null) return super.findClass(name);
的检查应该在方法的开头。此外,让方法返回一个新的ClassLoader非常可能是错误的(因为您希望所有文件都只有一个加载器)。 - bestsssClassLoader#getResources()
并传递一个空字符串将为您提供所有类路径资源的URL枚举。另请参见https://dev59.com/d3A75IYBdhLWcg3wkZ-A#3223019等。 - BalusC