java - 如何为运行时编译设置上下文类加载器的类路径?

标签 java compiler-construction weblogic java-6

我想在运行时在 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 选项时,我似乎找不到字符串形式的“上下文类路径”。以下是一些“足够好”的技巧:

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("/", "\\"));

但它不会生成上下文类加载器的完整类路径。我该怎么做,可靠吗?可以吗?

最佳答案

WebLogic 10.3.6 有一个相当复杂的 ClassLoader 实现。幸运的是,用于 Web 应用程序的类加载器公开了一个 getClassPath 方法。

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();

关于java - 如何为运行时编译设置上下文类加载器的类路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23293534/

相关文章:

tomcat - web.xml 是如何调用的?谁调用了 web.xml

java - 访问存储在 .jar 中的 PDF 文件

Java : Writing a String to a JPG File

c++ - gcc 编译器标志以抑制编译期间模板错误的模板扩展?

c++ - 如何实现对适当虚表条目的跳转调用

java - weblogic springframework TypeMismatchException 转换失败

java - 关于 future 的好文档/书

java - 当我按空格键时我的子弹没有发射

windows - 是否可以使用 Go 编译器为其他操作系统分发可执行文件?

jboss - 持久化单元,不同的 hibernate.transaction.manager_lookup_class 属性